Kerosive Kerosive - 14 days ago 9
Python Question

Django admin make changes to selected user?

So I have created a inline class in my admin.py and some actions to update a selected user. The problem I am facing is that when I select a user and perform said action it only ever updates the admin user....which I am guessing is because I am using

request
. I am trying to get the action to update the selected user(s) and not the admin user initiating the action, but I have been struggling with it for a couple days now off and on trying to figure this out. When using
queryset
I get error messages saying
'Queryset' object has no attribute 'profile'
but I am not sure what else to use here. So mu question is, is what I am trying to do possible and if so any guidance on how to get this working would be greatly appreciated. Please see my code below.

admin.py

admin.site.unregister(User)


class ProfileAdminInLine(admin.StackedInline):
model = Profile


class ProfileAdmin(UserAdmin):
list_display = ['username', 'email', 'first_name', 'last_name',
'rewards_punch_card', 'rewards_tier']
list_select_related = True
inlines = [ProfileAdminInLine]

actions = ['pc_add_1', 'pc_add_2', 'pc_add_3', 'pc_add_4', 'pc_add_5',
'pc_add_6', 'pc_add_7', 'pc_add_8', 'pc_add_9']

def rewards_tier(self, user):
return user.profile.rewards_tier

def rewards_punch_card(self, user):
return user.profile.rewards_current

def pc_add_1(self, request, queryset):

punch_card = request.user.profile.rewards_current
tier = request.user.profile.rewards_tier
credits = request.user.profile.rewards_credits

user_profile = request.user.profile

punch_cards_updated = punch_card + 1

if punch_cards_updated == 10:
request.user.profile.rewards_current = 0
user_profile.save()
if tier == 1:
request.user.profile.rewards_tier = tier + 1
request.user.profile.rewards_credits = credits + 25
user_profile.save()
elif tier == 2:
request.user.profile.rewards_tier = tier + 1
request.user.profile.rewards_credits = credits + 30
user_profile.save()
elif tier == 3:
request.user.profile.rewards_tier = tier + 1
request.user.profile.rewards_credits = credits + 35
user_profile.save()
elif tier == 4:
request.user.profile.rewards_tier = tier + 1
request.user.profile.rewards_credits = credits + 40
user_profile.save()
elif tier == 5:
request.user.profile.rewards_credits = credits + 50
user_profile.save()
elif tier == 6:
request.user.profile.rewards_credits = credits + 50
user_profile.save()

else:
request.user.profile.rewards_current = punch_card + 1
user_profile.save()

self.message_user(request, "Users were successfully updated by 1 item.")

Answer

As I said in the comments, queryset is the set of selected user profiles. So you just need to iterate over that. Obviously, you also need to consistently use the profile from the loop, rather than from request.user.

def pc_add_1(self, request, queryset):

    for user_profile in queryset:

        punch_card = user_profile.rewards_current
        tier = user_profile.rewards_tier
        credits = user_profile.rewards_credits

        punch_cards_updated = punch_card + 1

        if punch_cards_updated == 10:
            user_profile.rewards_current = 0
            if tier == 1:
                user_profile.rewards_tier = tier + 1
                user_profile.rewards_credits = credits + 25
        ...
        user_profile.save()

(One minor point: you don't seem to be doing anything with punch_cards_updated; did you mean to set that back to user_profile.rewards_current?)

Comments