How to update Django model data

Viewed 570

I want to know how I can add data to the Django integer field after the ins.save in my code. For example, if the donation field is equal to 3, after the ins.save, I want to add 1 to it and therefore it will be equal to 4. My code is down below.


Donate View:

def donate(request):
    if request.method == "POST":
        title = request.POST['donationtitle']
        phonenumber = request.POST['phonenumber']
        category = request.POST['category']
        quantity = request.POST['quantity']
        location = request.POST['location']
        description = request.POST['description']
        ins = Donation(title = title, phonenumber = phonenumber, category = category, quantity = quantity, location = location, description = description, user=request.user, )
        ins.save()
    

return render(request,'donate.html')
2 Answers

You can try this.

from django.db.models import F
......
ins.save()
UserDetail.objects.filter(user=request.user).update(donations=F('donations') + 1)

This will increase the donations of request.user by 1 after ins.save()

Also instead of nullable donation field set default value to zero for your IntegerField in your UserDetail model

class UserDetail(models.Model):
    donations = models.IntegerField(default=0)

You don't really need a donations field to count the number of donations of a user as it can be done by a query using the Count aggregation function [Django docs]. For example the below query will give you all users and their donation counts:

from django.db.models import Count


# Assuming 'User' is your user model name
users = User.objects.annotate(donation_count=Count('donation'))

for user in users:
    print(user.username, user.donation_count)

# If we already have a user instance
donation_count = user.donation_set.count()

Moving further UserDetail appears to be a model that contains extra details about the user, but it has a problem that you are using a Foreign Key, instead of that you should be using a OneToOneField [Django docs] instead, and if you want donations in this model you can add a property that will make that query to this model:

class UserDetail(models.Model):
    points = models.IntegerField(blank=True, null = True,)
    user = models.OneToOneField(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
    ) # A user detail without a user doesn't make much sense, hence no null or blank allowed
    
    @property
    def donations(self):
        return self.user.donation_set.count()
Related