【发布时间】:2020-09-21 01:19:24
【问题描述】:
我是使用 DRF 为社交媒体克隆构建后端 API 的初学者。前端将在以后构建,而不是在 Django 中。我目前正在使用 Postman 与 API 进行交互。
我正在尝试实现您在 Facebook 或 Instagram 上的“点赞”功能。我无法通过 Postman 发送正确的数据来更新具有多对多关系的字段。
这是我的一些代码:
models.py
class User(AbstractUser):
liked_haikus = models.ManyToManyField('Haiku', through='Likes')
pass
class Haiku(models.Model):
user = models.ForeignKey(User, related_name='haikus', on_delete=models.CASCADE)
body = models.CharField(max_length=255)
liked_by = models.ManyToManyField('User', through='Likes')
created_at = models.DateTimeField(auto_now_add=True)
class Likes(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
haiku = models.ForeignKey(Haiku, on_delete=models.CASCADE)
序列化器.py
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['username', 'password', 'url', 'liked_haikus']
extra_kwargs = { 'password' : {'write_only': True}}
def create(self, validated_data):
password = validated_data.pop('password')
user = User(**validated_data)
user.set_password(password)
user.save()
token = Token.objects.create(user=user)
return user
class HaikuSerializer(serializers.ModelSerializer):
class Meta:
model = Haiku
fields = ['user', 'body', 'liked_by', 'created_at']
class LikesSerializer(serializers.ModelSerializer):
model = Likes
fields = ['haiku_id', 'user_id']
views.py
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = [permissions.IsAuthenticated]
@action(detail=True, methods=['get'])
def haikus(self, request, pk=None):
user = self.get_object()
serializer = serializers.HaikuSerializer(user.haikus.all(), many=True)
return Response(serializer.data)
class UserCreateViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = [permissions.AllowAny]
class HaikuViewSet(viewsets.ModelViewSet):
queryset = Haiku.objects.all()
serializer_class = HaikuSerializer
permission_classes = [permissions.IsAuthenticated]
class LikesViewSet(viewsets.ModelViewSet):
queryset = Likes.objects.all()
serializer_class = LikesSerializer
permission_classes = [permissions.IsAuthenticated]
urls.py
router = routers.DefaultRouter(trailing_slash=False)
router.register('users', views.UserViewSet)
router.register('haikus', views.HaikuViewSet)
router.register('register', views.UserCreateViewSet)
router.register('likes', views.LikesViewSet)
urlpatterns = [
path('admin/', admin.site.urls),
path('', include(router.urls)),
path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
path('api-auth-token', obtain_auth_token, name='api_token_auth')
]
使用 Django Admin,我可以手动将用户设置为喜欢帖子,数据库中的字段将更新并反映在 API 请求中。
使用 Postman,我尝试将 PUT 和 PATCH 都发送到,例如:
http://127.0.0.1:8000/haikus/2
使用“表单数据”,其中 key ="liked_by" 和 value="3"(其中 3 是 user_id)。我收到了 200 响应和端点的 JSON 数据,但数据没有变化。
我已尝试 GET 和 POST 到 http://127.0.0.1:8000/likes,但收到以下错误消息:
AttributeError: 'list' 对象没有属性 'values'
我查看了 DRF 文档中的嵌套序列化程序,但它们的用例似乎并不完全相同。
如何更正我的代码并使用 Postman 正确更新多对多字段?
我想我可能需要为一个或多个 ViewSet 或 Serializer 编写一个更新函数,但我不知道是哪一个,也不知道该怎么做。
感谢所有指导、更正和资源。
【问题讨论】:
-
可能无法正常工作,因为在
LikesSerializer中您忘记在model和fields之前传递class Meta和fields
标签: django django-rest-framework postman