问题
This is my serializer:
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = ('user', 'post', 'reblog',)
def create(self, validated_data):
post = Post(
user = validated_data['user'],
post = validated_data['post'],
)
post.save()
# manually create a list of "reblog" users
post.reblog.add(validated_data['user'])
return post
and this is my model:
class Post(models.Model):
user = models.ForeignKey(User)
post = models.CharField(max_length=400)
reblog = models.ManyToManyField(User)
Now, I don't want my reblog field to ever be null in the database (it can be an empty list, but not null). So I did not set "null=True" in the model field. However, the end user should not have to provide a list of "reblog" users when creating a post (I'll do that manually in the create() mtehod).
I know that here: http://www.django-rest-framework.org/api-guide/fields/#core-arguments it says I can add "required = false" to a serializer field but the fields I am using in my serializer are directly coming from the model (i.e., fields = ('reblog')).
From my understanding, I can't add "required = false" to my model because here: https://docs.djangoproject.com/en/1.8/ref/models/fields/ it does not mention "required" as a parameter to a model field.
With that said, how can I get my "reblog" ModelSerializer field to not be required during serailzation / deserialization?
Edit: the view which handles the post request sent is:
class post_list(APIView):
"""
List all posts or create a new post.
"""
permission_classes = (IsAuthenticated,)
def get(self, request):
posts = Post.objects.all()
serializer = PostSerializer(posts, many=True)
return Response(serializer.data)
def post(self, request):
serializer = PostSerializer(data=request.DATA)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
pip freeze:
You are using pip version 6.1.1, however version 7.1.2 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
Django==1.8
djangorestframework==3.1.1
uWSGI==2.0.10
回答1:
Add the parameter blank=True
to the model field:
class Post(models.Model):
user = models.ForeignKey(User)
post = models.CharField(max_length=400)
reblog = models.ManyToManyField(User, blank=True)
#^^^^^^^^^^
Now, the parameter may be omitted on requests, but it may never be a NULL
value.
Altogether now:
urls.py
(with serializers.py
essentially inlined):
from django.conf.urls import url, include
from rest_framework import routers, serializers, viewsets
from proj.models import Post
# Serializers define the API representation.
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = ('user', 'post', 'reblog',)
def create(self, validated_data):
post = Post(
user = validated_data['user'],
post = validated_data['post'],
)
post.save()
# manually create a list of "reblog" users
post.reblog.add(validated_data['user'])
return post
class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
# Routers provide an easy way of automatically determining the URL conf.
router = routers.DefaultRouter()
router.register(r'Post', PostViewSet)
# Wire up our API using automatic URL routing.
# Additionally, we include login URLs for the browsable API.
urlpatterns = [
url(r'^', include(router.urls)),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]
models.py
:
from django.contrib.auth.models import User
from django.db import models
class Post(models.Model):
user = models.ForeignKey(User)
post = models.CharField(max_length=400)
reblog = models.ManyToManyField(User, blank=True,related_name='reblog_users')
Now, when I send the POST request:
{
"user": 1,
"post": "foo"
}
It returns:
{
"user": 1,
"post": "foo",
"reblog": [
1
]
}
pip freeze
:
Django==1.8.4
djangorestframework==3.2.4
来源:https://stackoverflow.com/questions/33001834/djangorestframework-correct-way-to-add-required-false-to-a-modelserializer