DjangoRestFramework - correct way to add “required = false” to a ModelSerializer field?

丶灬走出姿态 提交于 2019-12-24 03:43:00

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!