我研究了这个question,但我认为是不同的。
让我进一步解释一下。我有一个名为DetailTrackSerializer
的序列化程序来序列化我的Track
模型,并且在TaggedSerializer
中嵌套了一个DetailTrackSerializer
。
class DetailTrackSerializer(serializers.ModelSerializer):
id = serializers.IntegerField(read_only=True)
title = serializers.CharField(max_length=120)
link = serializers.URLField(max_length=120)
tagged_set = TaggedSerializer(many=True)
artist = ArtistSerializer()
class Meta:
model = Track
fields = ('id', 'artist', 'title', 'link', 'tagged_set',)
class TaggedSerializer(serializers.ModelSerializer):
tag = TagSerializer()
class Meta:
model = Tagged
fields = ('tag',)
class TagSerializer(serializers.ModelSerializer):
class Meta:
model = Tag
fields = ('name',)
当前,此DetailTrackSerializer
返回的是这样的json
{
"tracks": [
{
"id": 168,
"artist": {
"id": 163,
"name": "Gob"
},
"title": "Face the Ashes",
"link": "",
"tagged_set": [
{
"tag": {
"id": 1356,
"name": "punk rock"
}
},
{
"tag": {
"id": 1356,
"name": "punk rock"
}
},
{
"tag": {
"id": 1356,
"name": "punk rock"
}
},
...
列表继续,如果该曲目中有100个“ punk rock”标签,它将显示100次,并且可能不仅还有“ punk rock”,还有另一个标签。我需要的是这样的东西
{
"tracks": [
{
"id": 168,
"artist": {
"id": 163,
"name": "Gob"
},
"title": "Face the Ashes",
"link": "",
"tagged_set": [
{
"tag": {
"id": 1356,
"name": "punk rock"
},
"frequency": 100,
},
{
"tag": {
"id": 546,
"name": "pop"
},
"frequency": 236,
},
...
每个标签仅出现一次,并具有其频率。 注意:我也在使用Django Rest Framework
编辑:models.py
class Tagged(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, default=1)
track = models.ForeignKey(Track, on_delete=models.CASCADE)
tag = models.ForeignKey(Tag, on_delete=models.CASCADE)
class Tag(models.Model):
name = models.CharField(max_length=255, unique=True)
class Track(models.Model):
artist = models.ForeignKey(Artist, on_delete=models.CASCADE)
title = models.CharField(max_length=255)
link = models.URLField(max_length=255, blank=True)
tags = models.ManyToManyField(Tag, through='Tagged', blank=True)
答案 0 :(得分:1)
从您的Tagged
中我了解到 Data Redundancy
的可能性很大,这就是您的tagged_set
多次显示的原因。
我要说的是,这不是您的序列化器的Representation Problem
,而不是它是您的模型的Implementation Problem
。 br />
因此,unique_together
属性将解决此问题,
class Tagged(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, default=1)
track = models.ForeignKey(Track, on_delete=models.CASCADE)
tag = models.ForeignKey(Tag, on_delete=models.CASCADE)
class Meta:
unique_together = ('track', 'tag')
更改模型后,请执行makemigrations
和migration
。
注意:在进行migration
时,您可能会遇到django.db.utils.IntegrityError: UNIQUE constraint failed
的异常情况。因此,删除Tagged
模型中的所有条目
答案 1 :(得分:0)
Edwin Harly,在“跟踪”,“标记”和“标记”模型之间有一些数据重叠。如果您接受,建议删除标记的模型。如果要保存哪个用户创建标签,请在标签模型中添加用户字段。
class Tag(models.Model):
name = models.CharField(max_length=255, unique=True)
user = models.ForeignKey(User, on_delete=models.CASCADE, default=1)
class Track(models.Model):
artist = models.ForeignKey(Artist, on_delete=models.CASCADE)
title = models.CharField(max_length=255)
link = models.URLField(max_length=255, blank=True)
tags = models.ManyToManyField(Tag, through='Tagged', blank=True)
然后,您可以像这样使用序列化器:
class DetailTrackSerializer(serializers.ModelSerializer):
id = serializers.IntegerField(read_only=True)
title = serializers.CharField(max_length=120)
link = serializers.URLField(max_length=120)
tags = TagSerializer(many=True)
artist = ArtistSerializer()
class Meta:
model = Track
fields = ('id', 'artist', 'title', 'link', 'tags',)
class TagSerializer(serializers.ModelSerializer):
class Meta:
model = Tag
fields = ('name',)
答案 2 :(得分:0)
通读Django有关https://dev.to/claireparker/reasons-not-to-use-ids-in-css-4ni4的文档后,这就是我想出的解决方案
class DetailTrackSerializer(serializers.ModelSerializer):
id = serializers.IntegerField(read_only=True)
title = serializers.CharField(max_length=120)
link = serializers.URLField(max_length=120)
tags_frequency = serializers.SerializerMethodField()
artist = ArtistSerializer()
def get_tags_frequency(self, track):
tags = track.tags.all()
return tags.values('id', 'name').annotate(Count('id'))
class Meta:
model = Track
fields = ('id', 'artist', 'title', 'link', 'tags_frequency',)
这将给我这样的json表示形式
{
"tracks": [
{
"id": 168,
"artist": {
"id": 163,
"name": "Gob"
},
"title": "Face the Ashes",
"link": "",
"tags_frequency": [
{
"name": "punk rock",
"id": 1356,
"id__count": 100
},
{
"name": "punk",
"id": 1357,
"id__count": 60
}
]
},
{
"id": 169,
"artist": {
"id": 164,
"name": "Jeff And Sheri Easter"
},
"title": "The Moon And I (Ordinary Day Album Version)",
"link": "",
"tags_frequency": []
},