Фильтрация queryset через промежуточную модель
Пытаюсь отфильтровать queryset, на мой взгляд в точности как написано в документации, вылетает ошибка.
models.py
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
profile_picture = models.ImageField(default='/pictures/default.png', upload_to='pictures/', blank=True)
city = models.CharField(max_length=63, blank=True)
phone = models.CharField(max_length=15, blank=True)
friends = models.ManyToManyField('self', through='Friendship')
def __str__(self):
return self.user.__str__()
// friend1 всегда имеет id меньше, чем friend2
class Friendship(models.Model):
friend1 = models.ForeignKey(Profile, on_delete=models.CASCADE, related_name='friend1')
friend2 = models.ForeignKey(Profile, on_delete=models.CASCADE, related_name='friend2')
friend1_agree = models.BooleanField(default=False)
friend2_agree = models.BooleanField(default=False)
views.py
class FriendsView(LoginRequiredMixin, View):
login_url = '/login/'
template_name = 'userprofile/friends.html'
def get(self, request, *args, **kwargs):
friends = Profile.objects.filter(friendship__friend1_agree=True)
args = {'friends': friends}
print('friends : ', friends)
return render(request, self.template_name, args)
Ошибка возникает на строке friends = ..., сама ошибка:
Traceback (most recent call last):
File "/home/dima/my_python/greenleaf/venv/lib/python3.6/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/home/dima/my_python/greenleaf/venv/lib/python3.6/site-packages/django/core/handlers/base.py", line 179, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/dima/my_python/greenleaf/venv/lib/python3.6/site-packages/django/views/generic/base.py", line 70, in view
return self.dispatch(request, *args, **kwargs)
File "/home/dima/my_python/greenleaf/venv/lib/python3.6/site-packages/django/contrib/auth/mixins.py", line 52, in dispatch
return super().dispatch(request, *args, **kwargs)
File "/home/dima/my_python/greenleaf/venv/lib/python3.6/site-packages/django/views/generic/base.py", line 98, in dispatch
return handler(request, *args, **kwargs)
File "/home/dima/my_python/greenleaf/userprofile/views.py", line 132, in get
friends = Profile.objects.filter(friendship__friend1_agree=True)
File "/home/dima/my_python/greenleaf/venv/lib/python3.6/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/home/dima/my_python/greenleaf/venv/lib/python3.6/site-packages/django/db/models/query.py", line 942, in filter
return self._filter_or_exclude(False, *args, **kwargs)
File "/home/dima/my_python/greenleaf/venv/lib/python3.6/site-packages/django/db/models/query.py", line 962, in _filter_or_exclude
clone._filter_or_exclude_inplace(negate, *args, **kwargs)
File "/home/dima/my_python/greenleaf/venv/lib/python3.6/site-packages/django/db/models/query.py", line 969, in _filter_or_exclude_inplace
self._query.add_q(Q(*args, **kwargs))
File "/home/dima/my_python/greenleaf/venv/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1358, in add_q
clause, _ = self._add_q(q_object, self.used_aliases)
File "/home/dima/my_python/greenleaf/venv/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1380, in _add_q
split_subq=split_subq, check_filterable=check_filterable,
File "/home/dima/my_python/greenleaf/venv/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1258, in build_filter
lookups, parts, reffed_expression = self.solve_lookup_type(arg)
File "/home/dima/my_python/greenleaf/venv/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1084, in solve_lookup_type
_, field, _, lookup_parts = self.names_to_path(lookup_splitted, self.get_meta())
File "/home/dima/my_python/greenleaf/venv/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1482, in names_to_path
"Choices are: %s" % (name, ", ".join(available)))
django.core.exceptions.FieldError: Cannot resolve keyword 'friendship' into field. Choices are: author, city, friend1, friend2, friends, like, phone, postcomment, profile_picture, user, user_id
Также пробовал фильтровать так: friends = Profile.objects.filter(friends__friend1_agree=True) снова появляется ошибка, но уже другая:
Traceback (most recent call last):
File "/home/dima/my_python/greenleaf/venv/lib/python3.6/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/home/dima/my_python/greenleaf/venv/lib/python3.6/site-packages/django/core/handlers/base.py", line 179, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/dima/my_python/greenleaf/venv/lib/python3.6/site-packages/django/views/generic/base.py", line 70, in view
return self.dispatch(request, *args, **kwargs)
File "/home/dima/my_python/greenleaf/venv/lib/python3.6/site-packages/django/contrib/auth/mixins.py", line 52, in dispatch
return super().dispatch(request, *args, **kwargs)
File "/home/dima/my_python/greenleaf/venv/lib/python3.6/site-packages/django/views/generic/base.py", line 98, in dispatch
return handler(request, *args, **kwargs)
File "/home/dima/my_python/greenleaf/userprofile/views.py", line 132, in get
friends = Profile.objects.filter(friends__friend1_agree=True)
File "/home/dima/my_python/greenleaf/venv/lib/python3.6/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/home/dima/my_python/greenleaf/venv/lib/python3.6/site-packages/django/db/models/query.py", line 942, in filter
return self._filter_or_exclude(False, *args, **kwargs)
File "/home/dima/my_python/greenleaf/venv/lib/python3.6/site-packages/django/db/models/query.py", line 962, in _filter_or_exclude
clone._filter_or_exclude_inplace(negate, *args, **kwargs)
File "/home/dima/my_python/greenleaf/venv/lib/python3.6/site-packages/django/db/models/query.py", line 969, in _filter_or_exclude_inplace
self._query.add_q(Q(*args, **kwargs))
File "/home/dima/my_python/greenleaf/venv/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1358, in add_q
clause, _ = self._add_q(q_object, self.used_aliases)
File "/home/dima/my_python/greenleaf/venv/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1380, in _add_q
split_subq=split_subq, check_filterable=check_filterable,
File "/home/dima/my_python/greenleaf/venv/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1319, in build_filter
condition = self.build_lookup(lookups, col, value)
File "/home/dima/my_python/greenleaf/venv/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1156, in build_lookup
raise FieldError('Related Field got invalid lookup: {}'.format(lookup_name))
django.core.exceptions.FieldError: Related Field got invalid lookup: friend1_agree
Смотрел как нужно делать здесь https://docs.djangoproject.com/en/3.1/topics/db/models/#extra-fields-on-many-to-many-relationships и здесь https://gist.github.com/jhgaylor/5873301
Использую django 3.1.1
UPD: я хотел получить профили друзей заданного человека, поэтому фильтровал так:
friends = Profile.objects.filter(friendship__friend1_agree=True,friendship__friend2_agree=True,user_id=request.id))
Я знаю, что можно получить эти профили, фильтруя модель Friendship, меня интересует почему не работает конкретно то, что я написал выше