Search code examples
djangosubquery

How do i limit choices for a field in a django model with respect to the data in previous field using foreignkey and limit_choices_to attribute?


class Property(models.Model):
    property_name = models.CharField(max_length=100)
    unit_name = models.CharField(max_length=100)

class Tenant(models.Model):
    tenant_name = models.CharField(max_length=100)
    rent_unit = models.ForeignKey(Property, on_delete=models.SET_NULL)

class Payment(models.Model):
    payment_name = models.ForeignKey(Tenant, on_delete=models.SET_NULL)
    payment_property = models.ForeignKey(Property, on_delete=models.SET_NULL, limit_choices_to={
        'pk__in': Property.objects.filter(unit_name=models.OuterRef('payment_name__rent_unit__unit_name'))
    })

I'am trying to limit the choices for the payment_property field in the Payment model based on the selected rent_unit in the Tenant model using Django's ForeignKey.limit_choices_to attribute with a subquery. But am getting this error when trying to execute makemigrations. ValueError: This queryset contains a reference to an outer query and may only be used in a subquery.
i was expecting to get a single choice for payment_property whenever i create a new Payment object and select a Tenant object, the available choices for the payment_property field should be limited to Property objects that have the same unit_name as the rent_unit of the selected Tenant object.


Solution

  • if you want chained foreignkey then you can use a third party package django-smart-selects. To check documentation click here

    But if you want to do it by yourself, you can do it as well. First create an api where you will send payment_name value as an argument and the api will return you filtered choices of payment_property. before selecting payment_name, payment_property choices will be empty. After selecting payment_name, using javascript call the api, and get filtered choices of payment_property and add choices to the select options.