I have three models:
class IntakeCase:
name = models.CharField(max_length=200)
record_request_status = models.CharField(max_length=4, null=True, choices=list(RECORD_REQUEST_STATUS))
class Organization(models.Model):
name = models.CharField(max_length=200, null=True)
org = models.TextField(max_length=300, null=True)
obsolete = models.BooleanField(default=False, null=True)
def __str__(self):
name = '%s (%s)' % (
self.name,
self.org)
if self.obsolete:
name = '%s (OBS)' % (name)
return name
class Agency:
intake_case = models.ForeignKey(IntakeCase, on_delete=models.CASCADE, related_name='agencies', null=True)
organization = models.ForeignKey(Organization, on_delete=models.CASCADE)
And a filter like so:
class IntakeCaseFilter(django_filters.FilterSet):
name = django_filters.CharFilter(field_name='name', lookup_expr='icontains')
agencies__organization__name = django_filters.ModelChoiceFilter(queryset=Organization.objects.all(), to_field_name='name')
class Meta:
model = IntakeCase
fields = [ 'name', 'record_request_status', 'agencies__organization__name' ]
My filter form looks like so:

Looking at the HTML source for the agencies__organization__name popup, I see this:
<option value=“Sample Dept">Sample Dept (SAMPLE PD)</option>
The _value_ is set to name (from to_field_name), but the label is set to the value of __str__ on the Organization model. The generated SQL also uses the __str__ value, which means nothing matches.
SELECT COUNT(*) AS "__count" FROM "myapp_intakecase" INNER JOIN "myapp_agency" ON ("myapp_intakecase"."id" = "myapp_agency"."intake_case_id") INNER JOIN "myapp_organization" ON ("myapp_agency"."organization_id" = "myapp_organization"."id") WHERE "myapp_organization"."name" = 'Sample Dept (SAMPLE PD)'; args=(‘Sample Dept (SAMPLE PD)',)
What I want is this:
SELECT COUNT(*) AS "__count" FROM "myapp_intakecase" INNER JOIN "myapp_agency" ON ("myapp_intakecase"."id" = "myapp_agency"."intake_case_id") INNER JOIN "myapp_organization" ON ("myapp_agency"."organization_id" = "myapp_organization"."id") WHERE "myapp_organization"."name" = 'Sample Dept'; args=(‘Sample Dept',)
If I override __str__ to always return
self.name, this “works” (giving the latter SQL).
However, I would like to keep my custom value of Organization’s __str__ for display purposes.
How can I alter the filter to use the name field's value instead of the value of __str__? Alternately, if there’s a better way to do this, happy to hear it.
thanks.
Paul