0

Please how can I filter a queryset in views using model @property method.

class TransactionData(models.Model):
    Nozzle_address = models.CharField(max_length=255)
    Device = models.ForeignKey(Devices, on_delete=models.CASCADE)
    Site = models.ForeignKey(Sites, on_delete=models.CASCADE, enter code hererelated_name='transaction_data')
    Pump_mac_address = models.CharField(max_length=255)

   
    @property
    def product_name(self):
        try:
            return f'{(Nozzle.objects.filter(Pump__Device__Device_unique_address=self.Pump_mac_address,Nozzle_address=self.Nozzle_address)).Product.Name}'
        except :
            pass

Basically I want to be able to write a query in views like this:

filtered_product = models.TransactionData.objects.filter(Site=Site_id, product_name='kero')

But django does not support this. I think I will need to write a custom manager where I can then query like this

filtered_product = models.TransactionData.objects.filter(Site=Site_id).product_name('Key')

The problem is that in the property method product_name am making use of Another model like Nozzle

Please how can i get this done... I know I would need to use either custom manager or queryset to get this work but can't just figure it out.. I really appreciate your help. Thanks

@Amin I used annotate as you suggested but doesn't work since the self is refered to the model instannce so not defined... Any Help is appreciated. i.e.

models.TransactionData.objects.annotate(product_name=(models.Nozzle.objects.filter(Pump__Device__Device_unique_address=self.Pump_mac_address,Nozzle_address=self.Nozzle_address)).Product.Name)
ray
  • 95
  • 2
  • 14

1 Answers1

0

You should use annotate:

models.TransactionData.objects.annotate(product_name=YOUR_ANNOTATION)

After that, you can access product_name as a field and filter by that

Docs in: https://docs.djangoproject.com/en/3.2/ref/models/querysets/#annotate

Amin
  • 2,605
  • 2
  • 7
  • 15
  • I used annotate as you suggested but doesn't work since the self is refered to the model instance so not defined... models.TransactionData.objects.annotate(product_name=(models.Nozzle.objects.filter(Pump__Device__Device_unique_address=self.Pump_mac_address,Nozzle_address=self.Nozzle_address)).Product.Name) – ray Nov 04 '21 at 08:09
  • I suspect your product name query is a bit to complex to write easily as an annotation. Although not ideal database design, you could add a product_name field to your model and then use the code in your property method and override model.save() to set the new field everytime the model gets changed. – Gavin Burnell Nov 04 '21 at 08:24