【发布时间】:2019-07-12 13:53:39
【问题描述】:
我正在为 Django 中的类似应用程序的 Twitter 创建 API,并且由于我实现了令牌身份验证 (rest-auth),因此在创建新推文时遇到了问题:
{
"author": [
"This field is required."
]
}
我试过 CreateAPIView:
class TweetCreateAPIView(CreateAPIView):
serializer_class = TweetModelSerializer
permission_classes = (IsAuthenticated,)
# I've also tried to add the author field mannualy
def perform_create(self, serializer):
serializer.save(author=self.request.user)
但它不起作用,所以我创建了自定义发布方法:
class TweetCreateAPIView(APIView):
permission_classes = (IsAuthenticated,)
def post(self, request, format=None):
serializer = TweetModelSerializer(data=request.data)
if serializer.is_valid():
serializer.save(author=request.user)
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
但它仍然无法识别创建推文的用户
型号:
class Tweet(models.Model):
retweeted_by = models.ManyToManyField(
TwitterUser, blank=True, related_name='retweets')
commented_tweet = models.ManyToManyField(
'self', related_name='comments', blank=True, symmetrical=False)
author = models.ForeignKey(
TwitterUser, on_delete=models.CASCADE, related_name='tweets')
content = models.CharField(max_length=280)
created_at = models.DateTimeField(auto_now_add=True)
liked_by = models.ManyToManyField(
TwitterUser, blank=True, related_name='likes')
objects = TweetManager()
def __str__(self):
return self.content
def get_comments(self):
comments = Tweet.objects.filter(commented_tweet__pk=self.pk)
return comments
def get_retweets(self):
retweets = TwitterUser.retweets(tweet__id=self.id)
def get_absolute_url(self):
return reverse('tweets:pk', kwargs={'pk': self.pk})
序列化器:
class TweetModelSerializer(serializers.ModelSerializer):
likes_count = serializers.SerializerMethodField()
already_liked = serializers.SerializerMethodField()
def get_likes_count(self, tweet):
return tweet.liked_by.all().count()
def get_already_liked(self, tweet):
user = None
request = self.context.get("request")
if request and hasattr(request, "user"):
user = request.user
if user is not None:
if user in tweet.liked_by.all():
return True
else:
return False
else:
pass
class Meta:
model = Tweet
fields = [
'id',
'author',
'commented_tweet',
'content',
'retweeted_by',
'likes_count',
'already_liked',
'created_at',
]
设置:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# 3rd party
'rest_framework',
'rest_framework.authtoken',
'rest_auth',
'django.contrib.sites',
'channels',
'allauth',
'allauth.account',
'rest_auth.registration',
'reset_migrations',
'corsheaders',
]
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
],
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.TokenAuthentication',
),
'DEFAULT_PAGINATION_CLASS': 'twitter.paginations.StandardResultsSetPagination',
'TEST_REQUEST_DEFAULT_FORMAT': 'json',
}
身份验证本身工作正常,包括注册,所以我不认为这是令牌的问题,但我不知道当 CreateAPIView 不起作用时错误在哪里。
【问题讨论】:
-
首先使用
ModelViewSet为您的模型轻松提供API 端点。但是您的序列化程序中的实际错误,您需要一个附加属性read_only_fields = ('author', )。让我知道它是否修复了错误,我会添加详细的答案。 -
@VaibhavVishal 是的,工作正常。我没有使用 ModelViewSet,因为我刚开始使用 django,所以我想玩代码并编写一些自定义方法。
-
太酷了.....
标签: django django-rest-framework