Django REST Framework (DRF):将当前用户 ID 设置为字段值
Django REST Framework (DRF): Set current user id as field value
我有模型 NewsModel 和 2 个序列化器:
models.py
class NewsModel(models.Model):
title = models.CharField('Заголовок', max_length=255, help_text='Максимальная длина - 255 символов')
announce = models.TextField('Анонс', help_text='Краткий анонс новости')
author = models.ForeignKey(settings.AUTH_USER_MODEL, help_text='Автор новости', related_name='news')
full_text = models.TextField('Полный текст новости', help_text='Полный текст новости')
pub_date = models.DateTimeField('Дата публикации', auto_now_add=True, default=timezone.now, help_text='Дата публикации')
def comments_count(self):
return NewsComment.objects.filter(news=self.id).count()
def get_author_full_name(self):
return self.author.get_full_name()
class Meta:
db_table = 'news'
ordering = ('-pub_date',)
serilizers.py:
from rest_framework import serializers
from .models import NewsModel
from extuser.serializers import UserMiniSerializer
class NewsReadSerializer(serializers.ModelSerializer):
author = UserMiniSerializer()
class Meta:
model = NewsModel
fields = ('id', 'title', 'announce', 'comments_count', 'reviews', 'author_name')
def get_author_full_name(self, obj):
return obj.get_author_full_name()
class NewsWriteSerializer(serializers.ModelSerializer):
def validate_author(self, value):
value = self.request.user.id
return value
class Meta:
model = NewsModel
I select 序列化程序在 api.py:
class NewsList(ListCreateAPIView):
queryset = NewsModel.objects.order_by('-pub_date')
def get_serializer_class(self, *args, **kwargs):
if self.request.method == 'GET':
return NewsReadSerializer
return NewsWriteSerializer
class Meta:
model = NewsModel
但是当我创建 NewsModel 项目时,我看到 错误 400:错误请求 [{'author': 'This field is required'}]
如何在创建新项目时将当前用户 ID 设置为 NewsItem.author 值?
我认为您没有正确使用序列化程序。设置请求相关数据的更好做法是在您的视图中覆盖 perform_create
:
def perform_create(self, serializer):
serializer.save(author=self.request.user)
def perform_update(self, serializer):
serializer.save(author=self.request.user)
然后将您的作者序列化程序设置为只读:
author = UserMiniSerializer(read_only=True)
这样您就可以简单地使用一个 NewsSerializer
进行读取和写入操作。
在 DRF 版本中,前 3 个字段必须是 allow_null=True 且默认值=None 的声明符。 DRF 不会 运行 检查没有此参数的字段。结果代码:
class NewsReadSerializer(serializers.ModelSerializer):
"""
Serializer only for reading.
author field serialized with other custom serializer
"""
author = UserMiniSerializer()
class Meta:
model = NewsModel
fields = ('id', 'title', 'announce', 'comments_count', 'reviews', 'author', 'pub_date',)
class NewsWriteSerializer(serializers.ModelSerializer):
"""
Serializer for creating and updating records.
author here is the instance of PrimaryKeyRelatedField, linked to all users
"""
author = serializers.PrimaryKeyRelatedField(
queryset=User.objects.all(), # Or User.objects.filter(active=True)
required=False,
allow_null=True,
default=None
)
# Get the current user from request context
def validate_author(self, value):
return self.context['request'].user
class Meta:
model = NewsModel
fields = ('title', 'announce', 'full_text', 'author',)
我会尝试这样的事情:
你的models.py
class NewsModel(models.Model):
title = models.CharField(
'Заголовок', max_length=255,
help_text='Максимальная длина - 255 символов')
announce = models.TextField('Анонс',
help_text='Краткий анонс новости')
author = models.ForeignKey(
settings.AUTH_USER_MODEL,
help_text='Автор новости', related_name='news')
full_text = models.TextField(
'Полный текст новости',
help_text='Полный текст новости')
pub_date = models.DateTimeField(
'Дата публикации', auto_now_add=True,
default=timezone.now, help_text='Дата публикации')
def comments_count(self):
return NewsComment.objects.filter(news=self.id).count()
def get_author_full_name(self):
return self.author.get_full_name()
class Meta:
db_table = 'news'
ordering = ('-pub_date',)
serializers.py
(参考:http://www.django-rest-framework.org/api-guide/validators/#currentuserdefault)
from <yourapp>.models import NewsModel
from rest_framework import serializers
class NewsModelSerializer(serializers.ModelSerializer):
author = serializers.HiddenField(default=serializers.CurrentUserDefault())
class Meta:
model = NewsModel
您还应该将 settings.py 设置为如下所示:
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',)
}
在新的 DRF 中你可以写
owner = serializers.HiddenField(
default=serializers.CurrentUserDefault()
)
见http://www.django-rest-framework.org/api-guide/validators/#currentuserdefault
我有模型 NewsModel 和 2 个序列化器:
models.py
class NewsModel(models.Model):
title = models.CharField('Заголовок', max_length=255, help_text='Максимальная длина - 255 символов')
announce = models.TextField('Анонс', help_text='Краткий анонс новости')
author = models.ForeignKey(settings.AUTH_USER_MODEL, help_text='Автор новости', related_name='news')
full_text = models.TextField('Полный текст новости', help_text='Полный текст новости')
pub_date = models.DateTimeField('Дата публикации', auto_now_add=True, default=timezone.now, help_text='Дата публикации')
def comments_count(self):
return NewsComment.objects.filter(news=self.id).count()
def get_author_full_name(self):
return self.author.get_full_name()
class Meta:
db_table = 'news'
ordering = ('-pub_date',)
serilizers.py:
from rest_framework import serializers
from .models import NewsModel
from extuser.serializers import UserMiniSerializer
class NewsReadSerializer(serializers.ModelSerializer):
author = UserMiniSerializer()
class Meta:
model = NewsModel
fields = ('id', 'title', 'announce', 'comments_count', 'reviews', 'author_name')
def get_author_full_name(self, obj):
return obj.get_author_full_name()
class NewsWriteSerializer(serializers.ModelSerializer):
def validate_author(self, value):
value = self.request.user.id
return value
class Meta:
model = NewsModel
I select 序列化程序在 api.py:
class NewsList(ListCreateAPIView):
queryset = NewsModel.objects.order_by('-pub_date')
def get_serializer_class(self, *args, **kwargs):
if self.request.method == 'GET':
return NewsReadSerializer
return NewsWriteSerializer
class Meta:
model = NewsModel
但是当我创建 NewsModel 项目时,我看到 错误 400:错误请求 [{'author': 'This field is required'}]
如何在创建新项目时将当前用户 ID 设置为 NewsItem.author 值?
我认为您没有正确使用序列化程序。设置请求相关数据的更好做法是在您的视图中覆盖 perform_create
:
def perform_create(self, serializer):
serializer.save(author=self.request.user)
def perform_update(self, serializer):
serializer.save(author=self.request.user)
然后将您的作者序列化程序设置为只读:
author = UserMiniSerializer(read_only=True)
这样您就可以简单地使用一个 NewsSerializer
进行读取和写入操作。
在 DRF 版本中,前 3 个字段必须是 allow_null=True 且默认值=None 的声明符。 DRF 不会 运行 检查没有此参数的字段。结果代码:
class NewsReadSerializer(serializers.ModelSerializer):
"""
Serializer only for reading.
author field serialized with other custom serializer
"""
author = UserMiniSerializer()
class Meta:
model = NewsModel
fields = ('id', 'title', 'announce', 'comments_count', 'reviews', 'author', 'pub_date',)
class NewsWriteSerializer(serializers.ModelSerializer):
"""
Serializer for creating and updating records.
author here is the instance of PrimaryKeyRelatedField, linked to all users
"""
author = serializers.PrimaryKeyRelatedField(
queryset=User.objects.all(), # Or User.objects.filter(active=True)
required=False,
allow_null=True,
default=None
)
# Get the current user from request context
def validate_author(self, value):
return self.context['request'].user
class Meta:
model = NewsModel
fields = ('title', 'announce', 'full_text', 'author',)
我会尝试这样的事情:
你的models.py
class NewsModel(models.Model):
title = models.CharField(
'Заголовок', max_length=255,
help_text='Максимальная длина - 255 символов')
announce = models.TextField('Анонс',
help_text='Краткий анонс новости')
author = models.ForeignKey(
settings.AUTH_USER_MODEL,
help_text='Автор новости', related_name='news')
full_text = models.TextField(
'Полный текст новости',
help_text='Полный текст новости')
pub_date = models.DateTimeField(
'Дата публикации', auto_now_add=True,
default=timezone.now, help_text='Дата публикации')
def comments_count(self):
return NewsComment.objects.filter(news=self.id).count()
def get_author_full_name(self):
return self.author.get_full_name()
class Meta:
db_table = 'news'
ordering = ('-pub_date',)
serializers.py
(参考:http://www.django-rest-framework.org/api-guide/validators/#currentuserdefault)
from <yourapp>.models import NewsModel
from rest_framework import serializers
class NewsModelSerializer(serializers.ModelSerializer):
author = serializers.HiddenField(default=serializers.CurrentUserDefault())
class Meta:
model = NewsModel
您还应该将 settings.py 设置为如下所示:
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',)
}
在新的 DRF 中你可以写
owner = serializers.HiddenField(
default=serializers.CurrentUserDefault()
)
见http://www.django-rest-framework.org/api-guide/validators/#currentuserdefault