是否可以在模型序列化器中获取当前用户?我希望这样做而不必脱离泛型,因为它是一项必须完成的简单任务。
我的模特:
class Activity(models.Model):
number = models.PositiveIntegerField(
blank=True, null=True, help_text="Activity number. For record keeping only.")
instructions = models.TextField()
difficulty = models.ForeignKey(Difficulty)
categories = models.ManyToManyField(Category)
boosters = models.ManyToManyField(Booster)
class Meta():
verbose_name_plural = "Activities"
我的序列化器:
class ActivitySerializer(serializers.ModelSerializer):
class Meta:
model = Activity
我的观点:
class ActivityDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Activity.objects.all()
serializer_class = ActivityDetailSerializer
如何返回模型,并附加一个字段user
,以便我的响应如下所示:
{
"id": 1,
"difficulty": 1,
"categories": [
1
],
"boosters": [
1
],
"current_user": 1 //Current authenticated user here
}
答案 0 :(得分:40)
我找到了解决DRF源代码的答案。
class ActivitySerializer(serializers.ModelSerializer):
# Create a custom method field
current_user = serializers.SerializerMethodField('_user')
# Use this method for the custom field
def _user(self, obj):
request = getattr(self.context, 'request', None)
if request:
return request.user
class Meta:
model = Activity
# Add our custom method to the fields of the serializer
fields = ('id','current_user')
关键是在ModelSerializer
内定义的方法可以访问自己的上下文,该上下文始终包含请求(在对其进行身份验证时包含用户)。由于我的权限仅适用于经过身份验证的用户,因此此处应始终存在一些内容。
这也可以在其他内置的djangorestframework序列化器中完成。
正如Braden Holt指出的那样,如果您的user
仍为空(即_user
正在返回None
),则可能是因为序列化程序未作为请求的一部分初始化上下文。要解决此问题,只需在初始化序列化程序时添加请求上下文:
serializer = ActivitySerializer(
data=request.data,
context={
'request': request
}
)
答案 1 :(得分:31)
在REST框架中将上下文传递给序列化程序,默认情况下包含请求。因此,您只需在序列化程序中使用self.context['request'].user
。
答案 2 :(得分:0)
我遇到了类似的问题-我尝试保存包含用户的模型,并尝试使用
user = serializers.StringRelatedField(read_only=True, default=serializers.CurrentUserDefault())
就像官方文档一样-但是会抛出一个错误,提示用户是'null'
。重写默认的create
方法,使用户从请求中获得帮助:
class FavoriteApartmentsSerializer(serializers.ModelSerializer):
user = serializers.StringRelatedField(read_only=True, default=serializers.CurrentUserDefault())
class Meta:
model = FavoriteApartments
exclude = (
'date_added',
)
def create(self, validated_data):
favoriteApartment = FavoriteApartments(
apartment=validated_data['apartment'],
user=self.context['request'].user
)
favoriteApartment.save()
return favoriteApartment
答案 3 :(得分:-2)
我修改了request.data:
JQuery(function($) {
$(document).on('turbolinks:load', function() {
$('.time').clockTimePicker();
});
});