django-mock-queries icon indicating copy to clipboard operation
django-mock-queries copied to clipboard

Filtering by related model with custom `related_query_name` doesn't work

Open kvbrg opened this issue 4 years ago • 1 comments

Suppose we have two models: Patient and Slot.

class Slot(Model):
   ...
   email = EmailField(...)
   patient = models.ForeignKey(
       'patients.Patient',
       related_name='slots',
       related_query_name='slot',
       ...
    )

And then we need to filter patients by related slot.

def get_patients():
   ...
   # patients is queryset of patients.Patient
   return patients.filter(slot__email__isnull=True)

It's simple and working code. But when we try to mock get_patients with MockSet of patients created with fabric we get an error.

django.core.exceptions.FieldError: Cannot resolve keyword 'slot' into field. Choices are ...'slots', ...

If we change filter to slots__email__isnull=True, it works in tests. But now we get an error in Django shell.

django.core.exceptions.FieldError: Cannot resolve keyword 'slots' into field. Choices are: ... 'slot', ...

It would be great to fix this! Thanks. 😊

kvbrg avatar Sep 17 '21 13:09 kvbrg

I have not completely debugged this, but is seems like https://github.com/stphivos/django-mock-queries/blob/30eb2df6dfe46b772733c196350a9a7f2ec8dbe7/django_mock_queries/utils.py#L69-L75 needs some reworking.

The actual stacktrace:

Traceback (most recent call last):
  File "/home/stefan/temp/intro/mysite/polls/tests/test_default.py", line 43, in test2
    print(Question.objects.filter(slot__isnull=False))
  File "/home/stefan/temp/intro/venv/lib/python3.6/site-packages/django_mock_queries/query.py", line 126, in filter
    return MockSet(*matches(*results, **attrs), clone=self)
  File "/home/stefan/temp/intro/venv/lib/python3.6/site-packages/django_mock_queries/utils.py", line 213, in matches
    disqualified = [x for x in source if is_disqualified(x, attrs, negated)]
  File "/home/stefan/temp/intro/venv/lib/python3.6/site-packages/django_mock_queries/utils.py", line 213, in <listcomp>
    disqualified = [x for x in source if is_disqualified(x, attrs, negated)]
  File "/home/stefan/temp/intro/venv/lib/python3.6/site-packages/django_mock_queries/utils.py", line 202, in is_disqualified
    attr_value, comparison = get_attribute(obj, attr_name)
  File "/home/stefan/temp/intro/venv/lib/python3.6/site-packages/django_mock_queries/utils.py", line 124, in get_attribute
    validate_field(attr_part, lookup_fields)
  File "/home/stefan/temp/intro/venv/lib/python3.6/site-packages/django_mock_queries/utils.py", line 91, in validate_field
    raise FieldError(message)
django.core.exceptions.FieldError: Cannot resolve keyword 'slot' into field. Choices are 'choice', 'id', 'pub_date', 'question_text', 'slots'.

stefan6419846 avatar May 10 '23 11:05 stefan6419846