Home > Software design >  access multiple many to many relationships in a django template
access multiple many to many relationships in a django template

Time:03-11

class Account(models.Model):
    accountId = models.CharField(max_length=20, primary_key=True)
    username = models.CharField(max_length=30)
    
    def __str__(self):
        return self.username
class Project(models.Model):
    projectId = models.CharField(max_length=20, primary_key=True, default=idgen)
    projectName = models.CharField(max_length=20)
    projectOwner = models.ForeignKey(User, on_delete=models.CASCADE, related_name="owner")
    projectSize = models.IntegerField(default=25)
    projectGuests = models.ManyToManyField(User, related_name="guests")
    projectAccounts = models.ManyToManyField(Account, "accounts")

    def __str__(self):
        return self.projectId

In this code, users can have multiple projects and projects can have multiple accounts. Is there any way to pass just the 'user' to the template (or without passing anything since we can get the user using the request) to get all the accounts in all the projects that the user owns without using a for loop? cause I have to display a count of accounts in total that the user owns.

for example, if the user had 2 projects and each project had 2 accounts... is there any way to get the final value 4 in the template just using the user object?

CodePudding user response:

Try this Query

accounts = Project.objects.filter(projectOwner=request.user).projectAccounts_set.all()

CodePudding user response:

It is best to perform such arithmetic in Django views rather than templates 21404051.

First select all Projects related to request.user by

projects = Project.objects.filter(projectOwner=request.user)
                  .annotate(pc = Count('projectAccounts'))
                  .aggregate(total = Sum('pc'))

Now in template

{{ projects.total }}

CodePudding user response:

I decided to do it in views.py after all since it looks impossible to do in templates.

accs = []
for project in request.user.owner.all():
    for account in project.projectAccounts.all():
        accs.append(account)
accs = list( dict.fromkeys(accs))

this was a simple solution. pretty sure there are way easier and more efficient ways to do this.

  • Related