django - 通过模型序列化过滤嵌套的 DRF
问题描述
我的每个模型都继承自基本模型,其中包含publishing_status
帮助我控制对象是否包含在返回数据中的字段。
class BaseModel(models.Model):
class PublishingStatus(models.TextChoices):
ACCEPTED = 'accepted', 'Accepted'
REJECTED = 'rejected', 'Rejected'
publishing_status = models.CharField(
max_length=9,
choices=PublishingStatus.choices,
default=PublishingStatus.DRAFT,
help_text="Publishing status represents the state of the object. By default it is 'draft'"
)
class Meta:
abstract = True
这是两个模型Word
,Homonym
它们都继承自BaseModel
:
class Word(BaseModel):
definition = models.CharField(max_length=255)
homonyms = models.ManyToManyField('self', through='Homonym', through_fields=('homonym', 'word'))
class Homonym(BaseModel):
homonym = models.ForeignKey(Word, on_delete=models.CASCADE, related_name="homonyms")
word = models.ForeignKey(Word, on_delete=models.CASCADE, related_name="word_homonyms")
同音词基本上也是单词,所以我在这里有自我参考,但是通过模型Homonym
,我可以控制这些关系是否公开或不用于我的网站。
然后按照序列化程序,可能应该在此处传递解决方案:
class HomonymSerializer(serializers.ModelSerializer):
class Meta:
model = Homonym
fields = '__all__'
class WordSerializer(serializers.ModelSerializer):
homonyms = HomonymSerializer(many=True)
class Meta:
model = Word
fields = '__all__'
问题:目前,无论是否接受,都会显示所有同音异义词。如何将嵌套序列化程序限制为仅包含与 ? 的同音词publishing_status="accepted"
?
这是我的看法:
class WordRetrieveView(RetrieveAPIView):
serializer_class = WordSerializer
queryset = Word.objects.all().filter(publishing_status='accepted')
我目前的解决方案是将homonyms
字段定义为SerializerMethodField()
并在此处过滤查询集(我感觉这不是最好的方式,也不是 django 方式):
class WordSerializer(serializers.ModelSerializer):
homonyms = serializers.SerializerMethodField()
class Meta:
model = Word
fields = '__all__'
@staticmethod
def get_homonyms(obj):
homonyms = Homonym.objects.all().filter(publishing_status='accepted', homonym_id=obj.id)
return [HomonymSerializer(Word.objects.get(id=h.homonym_id)).data for h in homonyms]
bdbd的方法
已删除的HomonymSerializer
删除get_homonyms
方法WordSerializer
class WordSerializer(serializers.ModelSerializer):
class Meta:
model = Word
fields = '__all__'
class WordRetrieveView(RetrieveAPIView):
serializer_class = WordSerializer
queryset = Word.objects.all().filter(publishing_status='accepted').prefetch_related(
Prefetch('homonyms', queryset=Homonym.objects.filter(publishing_status='accepted'))
)
解决方案
您的主要查询集只会影响返回的结果Word
,而不是相关的同音词。因此,如果您只想返回某个子集,您还需要对相关对象应用相同的过滤器。
在这种情况下,只需将查询集更改为:
Word.objects.filter(publishing_status='accepted').prefetch_related(
Prefetch('homonyms', queryset=Homonym.objects.filter(publishing_status='accepted'))
)
这将获得所有Word
被接受的 s,以及每个被接受的单词的任何相关同音异义词。
推荐阅读
- excel - Excel - 在单个公式中查找对应的值
- python - Python pcl 没有属性 from_array
- karate - 如何使用 karate.set() 在 json 中添加新键
- vbscript - QTP/UFT - 将 Browser().Page() 存储为变量
- redirect - Safari 在 http 重定向上丢失哈希参数
- javascript - 滑动到下一张幻灯片时,Slick 滑块的行为类似于 Bootstrap Carousel
- docker - 无法使用 Jenkins Pipeline 步骤中的 docker 命令执行 shell 脚本
- r - 如何从 R 中具有相同 uuid 的其他列获取最大和最小日期时间 + 文件名?
- python-2.7 - python random.randint() 没有返回任何值
- javascript - 'Access-Control-Allow-Origin' 与 jQuery getJSON