Django model query with Foreign key and get logged in user

Viewed 552

Hi I am trying to add "fields" to my django projects that would be calculated based on query..

Basically I have 2 models one is a user which is an extension of Abstract user

class CustomUser(AbstractUser):
    pass

and my main model is Project

class Project(models.Model):
    id = models.AutoField(primary_key=True)
    user = models.ForeignKey(CustomUser, on_delete=models.PROTECT, editable=False)
    name = models.CharField(max_length=20, editable=False)
    total = models.DecimalField(max_digits=6, decimal_places=2, editable=False)
    created = models.DateTimeField(auto_now_add=True, editable=False, null=False, blank=False)
    this_month = datetime.datetime.now().month
    allprojectsthismonth = Project.objects.filter(created__month=this_month)

    def __str__(self):
        return self.name

I create Project objects via a web form using this view:

def homepage(request):
    if request.method == "POST":
        project = Project()
        name = request.POST.get('name')
        total = request.POST.get('total')
        created = datetime.datetime.now()
        user = request.user
        project.user = user
        project.name = name
        project.total = total
        project.created = created
        project.save()
        
        #return HttpResponse(reverse("homepage.views.homepage"))
        return render(request, 'homepage.html')
    else:

        return render(request, 'homepage.html')

What I need now is to have a queryset that gets me the combination of the total of a given user Project object so that I can make calculations on it, how would I go about doing that?

ideally I would get the logged in user and I could add to my view the sum of all Project.object.total with user = currently logged in.

Thanks

EDIT: Would this work?

class Project(models.Model):
id = models.AutoField(primary_key=True)
user = models.ForeignKey(CustomUser, on_delete=models.PROTECT, editable=False)
name = models.CharField(max_length=20, editable=False)
total = models.DecimalField(max_digits=6, decimal_places=2, editable=False)
created = models.DateTimeField(auto_now_add=True, editable=False, null=False, blank=False)
this_month = datetime.datetime.now().month
projectsthismonth = self.objects.filter(created__month=this_month)

def monthlyTotal(self,request):
    projectsthismonth.objects.filter(
        user=request.user
    ).aggregate(
        sum_total=Sum('total')
    )['sum_total']

I seem to be missing something however.

1 Answers

You can obtain the queryset of the Projects where the user is the logged in user with:

Project.objects.filter(user=request.user)

If you want to make simple aggregates (like sum, count, etc.), you better use .aggregate(…) [Django-doc] since then the calculations are done at the database level. For example:

from django.db.models import Sum

Project.objects.filter(
    user=request.user
).aggregate(
    sum_total=Sum('total')
)['sum_total']

will retrieve the sum of the totals of the Projects with user=request.user, this will be None if there are no projects related to the user at all.

from django.utils.timezone import now

class Project(models.Model):
    id = models.AutoField(primary_key=True)
    user = models.ForeignKey(CustomUser, on_delete=models.PROTECT, editable=False)
    name = models.CharField(max_length=20, editable=False)
    total = models.DecimalField(max_digits=6, decimal_places=2, editable=False)
    created = models.DateTimeField(auto_now_add=True)
    
    def monthlyTotal(self,user):
        this_month = now().month
        return Project.objects.filter(
            created__month=this_month,
            user=user
        ).aggregate(
            sum_total=Sum('total')
        )['sum_total']

Note: You can limit views to a view to authenticated users with the @login_required decorator [Django-doc].

Related