Martimus
Martimus

Reputation: 1

Django: Join multiple models on a field value for use in a Django template

I'm working in Django 2.0. I have multiple models which share a common field, and am trying to find the related objects. Schematically, given models Model1 and Model2, for each Model1 in a QuerySet, we want to find the corresponding Model2 object such that

Model1.property == Model2.property. 

In this application, there will be at most one, but possibly no, Model2s that meet this condition. This QuerySet will be used in a Django template for displaying results.

Now, I have several ideas as to how to solve this, but I was wondering if there was a standard solution.

Consideration: I know that Django template language does not have a builtin way to find an object with a particular property value

Ideas:

1) For loop in template. Iterate through the Model2s, evaluating Model2.property and testing Model2.property == Model1.property. Storing the Model2 if True. Seems very clunky, and against the philosophy of the Django template language.

2) Deal with it in python. Perhaps attach a new property to Model1

Model1.property.model2 = Model2.objects.filter(property=property)

or use a try/expect block with "get"

3) Deal with it in the query. Perhaps Annotate the results of retrieving the queryset for Model1 with the related Model2s

4) Maybe a custom template tag to add this functionality into the Django template?

Here are my models, for reference:

class ModuleSubscription(models.Model):
subscriber = models.ForeignKey(User, on_delete=models.CASCADE)  # owner of module
module = models.ForeignKey(Module, on_delete=models.CASCADE)  # id of owned module


class ModuleAssignment(models.Model):
delegation = models.ForeignKey(Delegation, on_delete=models.CASCADE)
module = models.ForeignKey(Module, on_delete=models.CASCADE)  # assigned module
access_granted = models.BooleanField(default=False)
module_log = models.ForeignKey(ModuleLog, default=None, on_delete=models.SET_DEFAULT, null=True)

Now, I need the filter ModuleSubscription by subscriber and ModuleAssignment by delegation, and then find the places where the resulting ModuleSubscription.module == ModuleAssignment.module . The reason is that, for each ModuleSubscription, I need the access_granted property from the corresponding ModuleAssignment, if it exists. Then, in the template, I need to loop throughall of the filtered ModuleSubscriptions and display the associated ModuleAssignment.access_granted

Upvotes: 0

Views: 465

Answers (1)

IVNSTN
IVNSTN

Reputation: 9334

(in addition to my comment) I was talking about the table where all the grants would be exposed. Probably I misunderstood what delegation is supposed to mean here.

# filtering part
modules = ModuleSubscription.objects.filter(subscriber=_s)
grants = ModuleAssignment.objects.filter(delegation=_d, module__in=modules)

# template part
for g in grants:
  ...

is that it?

Upvotes: 0

Related Questions