Фильтрация по полю ForeignKey в DRF
У меня есть несколько моделей:
class Page(models.Model):
date = models.DateField("Post date")
title = models.CharField(max_length=255)
chinese = models.TextField()
base = models.TextField()
published = models.BooleanField()
premium = models.BooleanField()
json = JSONField(default=dict, null=True, )
category = models.ManyToManyField(
Category)
calculated_hsk = models.DecimalField(
default=1, max_digits=3, decimal_places=2)
display_hsk = models.ForeignKey(HSKLevels, on_delete=models.SET_NULL, null=True)
image = models.ImageField(upload_to=imageFile, null=True, max_length=255)
sound = models.FileField(null=True, max_length=255)
url = models.URLField(max_length = 255, null=True)
class Sentence(models.Model):
sentence = JSONField(default=dict, null=True, )
article = models.ForeignKey(
Page,
on_delete=models.SET_NULL,
null=True
)
language = models.ForeignKey(Language, on_delete=models.SET_NULL, null=True)
class Translation(models.Model):
translation = models.TextField()
sentence = models.ForeignKey(
Sentence,
on_delete=models.SET_NULL,
null=True
)
language = models.ForeignKey(Language, on_delete=models.SET_NULL, null=True)
Я хочу иметь возможность фильтровать по языку предложений, чтобы я получал только те языки предложений, которые мне нужны.
У меня есть конечная точка DRF, настроенная следующим образом:
class ArticleView(generics.ListAPIView):
queryset = Page.objects.select_related().all()
serializer_class = ArticleSerializer
filter_backends = (filters.DjangoFilterBackend,)
pagination_class = LimitOffsetPagination
ordering_fields = ['date']
filter_class = MultiValue
И фильтр, подобный этому:
class MultiValue(filters.FilterSet):
published = filters.BooleanFilter(field_name='published')
premium = filters.BooleanFilter(field_name='premium')
category = NumberInFilter(field_name='category', lookup_expr='in')
calculated_hsk = NumberInFilter(field_name='calculated_hsk', lookup_expr='in')
display_hsk = NumberInFilter(field_name='display_hsk', lookup_expr='in')
start = filters.IsoDateTimeFilter(field_name="date", lookup_expr='gte')
end = filters.IsoDateTimeFilter(field_name="date", lookup_expr='lte')
language = filters.CharFilter(field_name="sentence.language.lang_code", lookup_expr='in')
И сериализаторы вроде этого:
class SentenceSerializer(serializers.ModelSerializer):
class Meta:
model = Sentence
depth = 1
fields = ['sentence', 'language']
class ArticleSerializer(serializers.ModelSerializer):
sound = serializers.FileField(required=False)
image = Base64ImageField(max_length=None, use_url=True)
category = serializers.PrimaryKeyRelatedField(
many=True, queryset=Category.objects.all())
url = serializers.CharField(allow_null=True, required=False, default=None, allow_blank=True)
english = serializers.CharField(source="base")
sentence_set = SentenceSerializer(required=False, many=True)
class Meta:
model = Page
depth = 1
fields = ['sentence_set', 'english','base','date', "chinese",
"calculated_hsk", "display_hsk", "id", "category", "title", "image", "published", "premium", "sound", "url"]
Цель состоит в том, чтобы иметь возможность сделать что-то вроде этого:
http://127.0.0.1:8000/api/v1/articles/62?lang_code=en
или может быть так:
http://127.0.0.1:8000/api/v1/articles/62?sentence__language__lang_code=en
и получать ТОЛЬКО элементы с lang_code "en" (или "zh", или любой другой возможный язык).
Существует ли хороший способ фильтрации по полям внешнего ключа таким образом?