Django REST 框架:"This field is required." 需要=False 和 unique_together
Django REST Framework : "This field is required." with required=False and unique_together
我想用 Django REST Framework 保存一个简单的模型。唯一的要求是 UserVote.created_by
在 perform_create()
方法中自动设置。失败并出现以下异常:
{
"created_by": [
"This field is required."
]
}
我猜是因为 unique_together 索引。
models.py:
class UserVote(models.Model):
created_by = models.ForeignKey(User, related_name='uservotes')
rating = models.ForeignKey(Rating)
class Meta:
unique_together = ('created_by', 'rating')
serializers.py
class UserVoteSerializer(serializers.ModelSerializer):
id = serializers.IntegerField(read_only=True)
created_by = UserSerializer(read_only=True)
class Meta:
model = UserVote
fields = ('id', 'rating', 'created_by')
views.py
class UserVoteViewSet(viewsets.ModelViewSet):
queryset = UserVote.objects.all()
serializer_class = UserVoteSerializer
permission_classes = (IsCreatedByOrReadOnly, )
def perform_create(self, serializer):
serializer.save(created_by=self.request.user)
如何在 DRF 中保存我的模型而无需用户提供 created_by
而是在代码中自动设置此字段?
提前致谢!
我有一个类似的问题,我通过显式创建一个新实例并将其传递给序列化程序来解决它。在 UserVoteViewSet
中,您必须将 perform_create
替换为 create
:
def create(self, request, *args, **kwargs):
uv = UserVote(created_by=self.request.user)
serializer = self.serializer_class(uv, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
另一种奇怪的方法是使用这样的信号
@receiver(pre_save, sender=UserVote)
def intercept_UserVote(sender, instance, *args, **kwargs):
import inspect
for frame_record in inspect.stack():
if frame_record[3]=='get_response':
request = frame_record[0].f_locals['request']
break
else:
request = None
instance.pre_save(request)
然后基本上你可以在你的模型中定义pre_save
def pre_save(self, request):
# do some other stuff
# Although it shouldn't happen but handle the case if request is None
self.created_by = request.user
这个系统的优点是您可以为每个模型使用相同的代码。如果您需要更改任何内容,只需更改 pre_save()
。您还可以添加更多内容
我在 views.py
中用一行代码解决了这个问题
def create(self, request, *args, **kwargs):
request.data.update({'created_by': request.user.id})
return super(UserVoteViewSet, self).create(request, *args, **kwargs)
由于此视图需要对用户进行身份验证,因此不要忘记为 rest_framework.permissions.IsAuthenticated
扩展 permission_classes
下面的代码对我有用。
即使我在多次实验后也遇到了同样的错误,所以在 class meta 中添加了 serializer.py
中的所有字段,如下所示 -
class Emp_UniSerializer( serializers.ModelSerializer ):
class Meta:
model = table
fields = '__all__' # To fetch For All Fields
extra_kwargs = {'std_code': {'required': False},'uni_code': {'required': False},'last_name': {'required': False},'first_name': {'required': False}}
在这里,我们可以更新 "extra_kwargs"
中的任何字段,它不会显示错误 ["This field is required."]
我想用 Django REST Framework 保存一个简单的模型。唯一的要求是 UserVote.created_by
在 perform_create()
方法中自动设置。失败并出现以下异常:
{
"created_by": [
"This field is required."
]
}
我猜是因为 unique_together 索引。
models.py:
class UserVote(models.Model):
created_by = models.ForeignKey(User, related_name='uservotes')
rating = models.ForeignKey(Rating)
class Meta:
unique_together = ('created_by', 'rating')
serializers.py
class UserVoteSerializer(serializers.ModelSerializer):
id = serializers.IntegerField(read_only=True)
created_by = UserSerializer(read_only=True)
class Meta:
model = UserVote
fields = ('id', 'rating', 'created_by')
views.py
class UserVoteViewSet(viewsets.ModelViewSet):
queryset = UserVote.objects.all()
serializer_class = UserVoteSerializer
permission_classes = (IsCreatedByOrReadOnly, )
def perform_create(self, serializer):
serializer.save(created_by=self.request.user)
如何在 DRF 中保存我的模型而无需用户提供 created_by
而是在代码中自动设置此字段?
提前致谢!
我有一个类似的问题,我通过显式创建一个新实例并将其传递给序列化程序来解决它。在 UserVoteViewSet
中,您必须将 perform_create
替换为 create
:
def create(self, request, *args, **kwargs):
uv = UserVote(created_by=self.request.user)
serializer = self.serializer_class(uv, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
另一种奇怪的方法是使用这样的信号
@receiver(pre_save, sender=UserVote)
def intercept_UserVote(sender, instance, *args, **kwargs):
import inspect
for frame_record in inspect.stack():
if frame_record[3]=='get_response':
request = frame_record[0].f_locals['request']
break
else:
request = None
instance.pre_save(request)
然后基本上你可以在你的模型中定义pre_save
def pre_save(self, request):
# do some other stuff
# Although it shouldn't happen but handle the case if request is None
self.created_by = request.user
这个系统的优点是您可以为每个模型使用相同的代码。如果您需要更改任何内容,只需更改 pre_save()
。您还可以添加更多内容
我在 views.py
def create(self, request, *args, **kwargs):
request.data.update({'created_by': request.user.id})
return super(UserVoteViewSet, self).create(request, *args, **kwargs)
由于此视图需要对用户进行身份验证,因此不要忘记为 rest_framework.permissions.IsAuthenticated
permission_classes
下面的代码对我有用。
即使我在多次实验后也遇到了同样的错误,所以在 class meta 中添加了 serializer.py
中的所有字段,如下所示 -
class Emp_UniSerializer( serializers.ModelSerializer ):
class Meta:
model = table
fields = '__all__' # To fetch For All Fields
extra_kwargs = {'std_code': {'required': False},'uni_code': {'required': False},'last_name': {'required': False},'first_name': {'required': False}}
在这里,我们可以更新 "extra_kwargs"
中的任何字段,它不会显示错误 ["This field is required."]