简体   繁体   English

Django模型与Foreignkey模型重复

[英]Django model get duplicated from foreignkey model

I have two models, one to create a title and one to create a vote for this title. 我有两种模型,一种用于创建标题,一种用于为此标题创建投票。

When I create more than one vote on the same title, I get duplicate titles, and I can't figure out why. 当我为同一标题创建多个投票时,会得到重复的标题,我不知道为什么。

Here is my vote 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__())

and the view to vote: 和投票意见:

@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)

If I print the number of title instances after creating the vote, the count is good, no duplicate, so I assume the duplication happens later. 如果在创建投票后打印标题实例的数量,则该计数很好,没有重复,因此我假设重复发生在以后。 Can you point me where/why the duplication happens? 您能指出我重复的位置/原因吗?

When I delete the vote, the title created by the duplication is deleted as well. 当我删除投票时,由重复创建的标题也将被删除。

Edit 1 : 编辑1:

I have tried to create a custom manager for the title models to block the duplication, but when the duplication happen while creating a vote, the title manager is not called. 我试图为标题模型创建自定义管理器以阻止重复,但是当在创建投票时发生重复时,不会调用标题管理器。

When I compare the origin models instance primary key with the duplication they are the same. 当我比较原始模型实例主键和重复键时,它们是相同的。

Edit 2: 编辑2:

trying to order the titles fields in artworks serializer 试图订购艺术品序列化器中的标题字段

my artworks serializer : 我的作品序列化器:

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')

my title serializer: 我的标题序列化器:

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',)

my artworks view: 我的作品视图:

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

When you order by the related field votes , this causes Django to do a left outer join. 当您按相关字段的votes排序时,这会导致Django执行左外部联接。 If a title is related to multiple votes, it is returned in the queryset once for each vote. 如果一个标题与多个投票相关,则每个查询在查询集中将其返回一次。

Note that saving the votes is not creating duplicates . 请注意,保存投票不会创建重复项 You can confirm this by ordering by a different field, and checking the count. 您可以通过在其他字段中排序并检查计数来确认这一点。 As you say in your question, the primary key of the duplicates is the same, so you have not created extra titles in the database, the queryset is just returning the same titles multiple times. 正如您在问题中说的那样,重复项的主键是相同的,因此您没有在数据库中创建额外的标题,queryset只是多次返回相同的标题。

Title.objects.order_by('pk').count()

To order by the number of votes, you need to annotate the queryset with the number of votes, then order by the annotation: 要按投票数排序,您需要用投票数注释查询集,然后按注释进行排序:

Title.objects.annotate(num_votes=Count('votes')).order_by('num_votes')

You can try to replace: 您可以尝试替换:

vote = Vote.objects.create(title=title, user=user)

to

vote, created = Vote.objects.get_or_create(title=title, user=user)

the probleme was coming from my title models : 问题出在我的头衔模特身上:

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

the ordering in meta was duplicating the model everytime i vote why is this happening? 每当我投票时,meta中的顺序都会复制该模型,为什么会这样呢? and how im suppose to order my title by the number of vote they get ? 以及我如何根据他们获得的投票数来排序我的头衔?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM