Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
405 views
in Technique[技术] by (71.8m points)

Django REST Framework(DRF) 怎么实现用户关系(followers,fans)的列表显示和增删关注用户?

现在有一个基本用户 model。已经在 model 里面设置了用户关系:

class User(models.Model):
    username = CharField()
    followers = ManyToManyField(
        'self',
        related_name="fans", symmetrical=False, )

用户的 serializer 已经写好:

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        field = ('id', 'username', )
User 的 list view 和 detail view 都没有问题。
我已经实现过了。

我现在想要实现用户关系的 API

那么假如获取用户关系的 API 为:

urlpatterns += [
    path("/api/users/<int:user_id>/<str:relationship>/", views.RelationshipList.as_view(), ),
]

那么 views 中的 RelationshipList 应该怎么实现:

class RelationshipList(...):
    ''':relationship: <followers|fans>'''

    multiple_lookup_fields = ('user_id', 'relationship')
    serializer_class = None  # ?
    queryset = None  # ?
    # ...other code...?

上面想要根据 url 是 /api/users/<user_id>/followers/ 或者是 /api/users/<user_id>/fans/ 显示了用户的关注或者粉丝列表。

RelationshipList 应该怎么实现?


我想要实现“[关注]” 用户和 "[取消关注]" 用户的功能;
那么是应该使用
/api/users/<user id>/followers/ 这个 API + POST or DELETE 作为关注和取消关注两个功能的开发?
还是另外使用一个 URL,编写另外一个 View class(上面的 API 用的是 Relationship)来实现?

因为在使用 DRF save 这样的 many to many field 不太熟,

怎么实现这个 [关注][取消关注] 的功能?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

可以考虑rest_framework_nested这个包
曾经写过一对多的情况,以下是凭记忆写的,只是大致思路

serializers:

class UserFansSerializer(serializers.ModelSerializer):
    # 粉丝主的id
    master_id = serializers.IntegerField(write_only=True) 
    username = serializers.CharField(read_only=True)
    
    class Meta:
        model = User
        field =(
            'id', 'username', 'master_id'
        )
    
    # create方法只是在粉丝主的fans字段中添加了新的对象
    def create(self, validated_data):
        master = User.object.get(id=validated_data.get('master_id'))
        master.fans.add(validated_data.get('id'))
        master.save()
        return master.fans.all()
    
    # 需要重写update, 更新fans字段
    def update(self, instance, validated_data):
        pass

views:

class UserFansViewSet(ModelViewSet):
    serializer_class = UserFansSerializer
    
    def get_queryset(self):
        self.master_pk = self.kwargs.get('master_pk')
        master = get_object_or_404(User, id=master_pk)
        queryset = master.fans.all()
        return queryset
     
    # 这里需要重写create方法,在self.get_serializer()方法的data参数中添加'master_pk'键值对
        
    # 需要重写删除行为
    def perform_destroy(self, instance):
        master = User.object.get(id=self.master_pk)
        master.fans.remove(instace)

urls:

from rest_framework import routers
from rest_framework_nested import routers as nested_routers

router = routers.SimpleRouter()
router.register(r'user', views.UserViewSet, 'user')

user_fans_router = nested_routers.NestedDefaultRouter(router, r'user', lookup='master')
user_fans_router.register(r'fans',views.UserFansViewSet, 'user_fans')

urlpatterns = router.urls + user_fans_router.urls

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...