[英]Django model get duplicated from foreignkey model
我有两种模型,一种用于创建标题,一种用于为此标题创建投票。
当我为同一标题创建多个投票时,会得到重复的标题,我不知道为什么。
这是我的投票模型,
class Vote(GenericModel):
"""
Model for vote on a title
"""
title = models.ForeignKey(Title, blank=True, related_name='votes')
user = models.ForeignKey(ArtLover, blank=True)
def __str__(self):
return _("vote on {}").format(self.title.__str__())
和投票意见:
@detail_route(methods=['post'])
def vote(self, request, *args, **kwargs):
"""
Create vote for a title
"""
title = Title.objects.get(text=kwargs.get('text'))
user = ArtLover.objects.get(id=request.user.id)
if title.user.id == user.id:
return Response(
_("You can't vote for your own title"),
status=status.HTTP_403_FORBIDDEN
)
if Vote.objects.filter(title=title, user=user).exists():
return Response(
_("Vote already exists"),
status=status.HTTP_409_CONFLICT
)
vote = Vote.objects.create(title=title, user=user)
return Response({
'vote': VoteSerializer(vote).data
}, status=status.HTTP_201_CREATED)
如果在创建投票后打印标题实例的数量,则该计数很好,没有重复,因此我假设重复发生在以后。 您能指出我重复的位置/原因吗?
当我删除投票时,由重复创建的标题也将被删除。
编辑1:
我试图为标题模型创建自定义管理器以阻止重复,但是当在创建投票时发生重复时,不会调用标题管理器。
当我比较原始模型实例主键和重复键时,它们是相同的。
编辑2:
试图订购艺术品序列化器中的标题字段
我的作品序列化器:
class ArtworkDetailSerializer(serializers.ModelSerializer):
"""
Detailed serializer for Artwork
"""
artist = serializers.CharField(source='artist.username', read_only=True)
titles = TitleSerializer(many=True)
emotions = serializers.SerializerMethodField()
class Meta:
model = Artwork
fields = ('id', 'file', 'artist', 'index', 'url', 'titles', 'emotions')
read_only_fields = ('id', 'artist', 'index', 'url', 'titles', 'emotions')
我的标题序列化器:
class TitleSerializer(serializers.ModelSerializer):
"""
Serializer for title suggested by user
"""
votes = VoteSerializer(many=True, read_only=True)
user = serializers.CharField(source='user.username', read_only=True)
artwork = serializers.CharField(source='artwork.url', read_only=True)
class Meta:
model = Title
fields = ('id', 'artwork', 'text', 'user', 'votes',)
read_only_fields = ('id', 'artwork', 'user', 'votes',)
我的作品视图:
class ArtworkView(viewsets.ModelViewSet):
"""
View that handle Artwork
"""
lookup_field = 'url'
queryset = Artwork.objects.all()
permission_classes = (
permissions.IsAuthenticatedOrReadOnly,
IsArtistOrReadOnly,
)
def get_serializer_class(self):
if self.action == 'retrieve':
return ArtworkDetailSerializer
return ArtworkSerializer
当您按相关字段的votes
排序时,这会导致Django执行左外部联接。 如果一个标题与多个投票相关,则每个查询在查询集中将其返回一次。
请注意,保存投票不会创建重复项 。 您可以通过在其他字段中排序并检查计数来确认这一点。 正如您在问题中说的那样,重复项的主键是相同的,因此您没有在数据库中创建额外的标题,queryset只是多次返回相同的标题。
Title.objects.order_by('pk').count()
要按投票数排序,您需要用投票数注释查询集,然后按注释进行排序:
Title.objects.annotate(num_votes=Count('votes')).order_by('num_votes')
您可以尝试替换:
vote = Vote.objects.create(title=title, user=user)
至
vote, created = Vote.objects.get_or_create(title=title, user=user)
问题出在我的头衔模特身上:
class Title(GenericModel):
"""
Model for title suggested by user
"""
class Meta:
ordering = ['votes']
text = models.CharField(_('text'), max_length=255)
artwork = models.ForeignKey(Artwork, blank=True, related_name='titles')
user = models.ForeignKey(ArtLover, blank=True)
def __str__(self):
return self.text
每当我投票时,meta中的顺序都会复制该模型,为什么会这样呢? 以及我如何根据他们获得的投票数来排序我的头衔?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.