通过mod实现多对多字段跟踪系统

2024-09-24 22:29:07 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在添加一个following/follower系统,并在我的profile模型中将其作为一个外来字段。问题是,我希望能够将多个信息保存到它中,就像某个特定用户开始跟踪其他未来信息时一样,因此我让多对多字段通过一个模型,如下所示:https://docs.djangoproject.com/en/3.0/topics/db/models/#extra-fields-on-many-to-many-relationships

求你了,我想知道我失去了什么

AttributeError at /api/opeyemi-odedeyi-ikx5yh/follow/
'User' object has no attribute 'following'

我试过这个:

你知道吗型号.py你知道吗

class Profile(models.Model):
    SEX= (
    ('M', 'Male'),
    ('F', 'Female'),
    )

    user          = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='profiles')
    date_of_birth = models.DateField(blank=True, verbose_name="DOB", null=True)
    bio           = models.TextField(max_length=500, blank=True, null=True)
    sex           = models.CharField(max_length=1, choices=SEX, blank=True, null=True)
    following     = models.ManyToManyField(settings.AUTH_USER_MODEL, blank=True, through='Follow', related_name='followed_by')
    updated_on    = models.DateTimeField(auto_now=True)


    def __str__(self):
        return self.user.fullname

class Follow(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='user_following')
    profile = models.ForeignKey(Profile, on_delete=models.CASCADE, related_name='profile')
    date_followed = models.DateField(auto_now_add=True)

你知道吗序列化程序.py你知道吗

class ProfileDetailedSerializer(serializers.ModelSerializer):
    user = serializers.SlugRelatedField(read_only=True, slug_field='slug')
    age = serializers.SerializerMethodField(read_only=True)

    following = serializers.SlugRelatedField(read_only=True, slug_field='slug', many=True)
    following_count = serializers.SerializerMethodField(read_only=True)
    user_has_followed = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = Profile
        fields = "__all__"

        read_only_fields = ('pk', 'user')

    def get_age(self, instance):
        today = date.today()
        dob = instance.date_of_birth
        if dob==None:
            return None
        return today.year - dob.year - ((today.month, today.day) < (dob.month, dob.day))

    def get_following_count(self, instance):
        return instance.following.count()

    def get_user_has_followed(self, instance):
        request = self.context.get("request")
        return instance.following.filter(pk=request.user.pk).exists()

你知道吗视图.py你知道吗

class UserFollowAPIView(APIView):
    '''
    Can follow(post) and unfollow(delete) the user
    '''
    serializer_class = ProfileDetailedSerializer
    permission_classes = [IsAuthenticated]

    def delete(self, request, slug):
        followUser = get_object_or_404(User, slug=slug)
        user = self.request.user

        followUser.following.remove(user)
        followUser.save()

        serializer_context = {"request": request}
        serializer = self.serializer_class(followUser, context=serializer_context)

        return Response(serializer.data, status=status.HTTP_200_OK)

    def post(self, request, slug):
        followUser = get_object_or_404(User, slug=slug)
        user = self.request.user

        followUser.following.add(user)
        followUser.save()

        serializer_context = {"request": request}
        serializer = self.serializer_class(followUser, context=serializer_context)

        return Response(serializer.data, status=status.HTTP_200_OK)

你知道吗网址.py你知道吗

path("<slug:slug>/follow/", UserFollowAPIView.as_view(), name="user-follow"),

注:

我使用slug是因为我在我的应用程序中没有使用username,所以我有一个slug字段,并使其成为查找字段,而不是普通的pk

序列化程序上下文是这样的:当它返回true时,用户不能跟随(即,他们不能跟随两次)


Tags: nameselftruereturnmodelsrequestdefcontext