如何计算Django中模型_集的差异?
我已经调查过了,但我觉得不一样。 让我进一步解释一下。我有一个名为如何计算Django中模型_集的差异?,django,django-models,django-rest-framework,django-serializer,Django,Django Models,Django Rest Framework,Django Serializer,我已经调查过了,但我觉得不一样。 让我进一步解释一下。我有一个名为DetailTrackSerializer的序列化程序来序列化我的Track模型,我在DetailTrackSerializer中嵌套了一个TaggedSerializer class DetailTrackSerializer(serializers.ModelSerializer): id = serializers.IntegerField(read_only=True) title = serializer
DetailTrackSerializer
的序列化程序来序列化我的Track
模型,我在DetailTrackSerializer
中嵌套了一个TaggedSerializer
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"
}
},
...
{
"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,
},
...
{
"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": []
},
这个列表还在继续,如果这首歌中有100个“朋克摇滚”标签,它会出现100次,而且可能还有另外一个标签,而不仅仅是“朋克摇滚”。我需要的是这样的东西
{
"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"
}
},
...
{
"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,
},
...
{
"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": []
},
每个标记只显示一次,并具有其频率。
注意:我也在使用Django Rest框架
编辑: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)
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',)
从您的
标记的
中,我了解到数据冗余的可能性很大,这就是为什么您的标记集
会多次显示的原因。我想说的是,这不是序列化程序的
表示问题,而是模型的实现问题
因此,unique\u合在一起
属性将解决问题,如下所示
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')
类标记(models.Model):
user=models.ForeignKey(user,on_delete=models.CASCADE,默认值=1)
track=models.ForeignKey(track,on_delete=models.CASCADE)
tag=models.ForeignKey(tag,on_delete=models.CASCADE)
类元:
一起唯一=('track','tag')
更改模型后,请执行makemigrations
和migration
注意:在执行迁移时
您可能会遇到acrossdjango.db.utils.IntegrityError:唯一约束失败
异常。因此,在阅读Django的文档后,删除标记的模型中的所有条目,这就是我提出的解决方案
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": "",
"tagged_set": [
{
"tag": {
"id": 1356,
"name": "punk rock"
}
},
{
"tag": {
"id": 1356,
"name": "punk rock"
}
},
{
"tag": {
"id": 1356,
"name": "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,
},
...
{
"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": []
},
我能看看你的模型吗?@MohammadAli当然,我已经更新了你的模型中的频率场在哪里的问题?@HemanthSP没有,这个频率必须从记录中计算出来。我恐怕这个唯一的组合是不可能的,因为多个用户必须能够使用相同的标签标记曲目
,但每个用户只能标记一次。然后,剩下的唯一选项是unique\u-together=('track','tag','user')
。我以前考虑过这个问题,但我有意不实现它,因为我需要从数据集导入数据,而数据集不包含关于哪个用户具有哪个跟踪的标签的信息。因此,我将user字段默认为id=1的user。您说过user
在您的上下文中是相同的,那么unique\u-together=('track','tag')
有什么问题吗?据我所知,如果同时使用unique\u=('track','tag'),“user A,track N,tag J”和“user B,track N,tag J”,这两条记录将不可能出现,我错了吗?是的,你是对的。但我不明白在你的背景下这是怎么造成问题的