【问题标题】:Making read_only fields while Updating , but not in CREATE Method in ModelSerializer在更新时制作只读字段,但不在 ModelSerializer 的 CREATE 方法中
【发布时间】:2018-09-20 04:34:28
【问题描述】:

我是 python 新手,我想在 Django 中创建一个 API,我面临的挑战之一是尝试使 UPDATE 端点和 CREATE 端点工作。

当我在更新过程中忽略了一些必填字段时,它可以工作,但对于 CREATE 方法不起作用,它会带来以下错误消息:

IntegrityError at /api/articles/comment/4/replies/ null value in column "author_id" violates not-null constraint DETAIL: Failing row contains (2018-09-20 04:24:36.225977+00, 89, English is better, null, null)

当我在序列化程序中删除 read_only 时,问题出现在 postman 中的 UPDATE 端点,如下所示:

{
    "comment": [
        "This field is required."
    ],
    "author": [
        "This field is required."
    ]
}

以下是我的代码sn-p:

我在serializers.py中的序列化器

class RepliesSerializer(serializers.ModelSerializer):


    class Meta:
        model = Replies
        fields = '__all__'
        read_only_fields = ('comment', 'author',)

views.py中的观点。

class RepliesView(APIView):
    permission_classes = (IsAuthenticated,)

    def get_object(self, pk):
        try:
            return Replies.objects.get(pk=pk)
        except Replies.DoesNotExist:
            raise Http404

    def post(self, request, commentID):

        content = request.data
        author = request.user.id

        content['author'] = author
        content['comment'] = commentID
        # print('--> ', author)
        # print('content ---> ',content)
        serializer = RepliesSerializer(data=content)
        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)

    def get(self,request, commentID):
        instance = Replies.objects.all()
        serializer = RepliesSerializer(instance, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def delete(self, request, Id, format=None):
        snippet = self.get_object(Id)
        snippet.delete()
        return Response({"message" : "Reply Deleted Successfully."}, status=status.HTTP_204_NO_CONTENT)


    def put(self, request, Id):

        content = self.get_object(Id)
        serializer = RepliesSerializer(content, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

model.py中的模型类

"""
class to declare an article
model. To be used for all articles
"""

from django.db import models
from django.utils import timezone

from authors.apps.articles.utils import generate_slug
from authors.apps.authentication.models import User


# noinspection SpellCheckingInspection
class Article(models.Model):
    """
    A model for an article
    """
    slug = models.SlugField(max_length=100, unique=True)

    author = models.ForeignKey(User, on_delete=models.CASCADE)

    title = models.CharField(max_length=255, null=False, blank=False,
                             error_messages={"required": "Write a short title for your article."})

    description = models.TextField(null=False, blank=False,
                                   error_messages={"required": "A description of your post is required."})

    body = models.TextField(null=False, blank=False,
                            error_messages={"required": "You cannot submit an article without body."})

    created_at = models.DateTimeField(auto_created=True, auto_now=False, default=timezone.now)

    updated_at = models.DateTimeField(auto_created=True, auto_now=False, default=timezone.now)

    favorited = models.BooleanField(default=False)

    favorites_count = models.IntegerField(default=0)

    photo_url = models.CharField(max_length=255, null=True)

    def __str__(self):

        """
        :return: string
        """
        return self.title

    def save(self, *args, **kwargs):
        """
        override default save() to generate slug
        :param args:
        :param kwargs:
        """
        self.slug = generate_slug(Article, self)

        super(Article, self).save(*args, **kwargs)

    class Meta:
        get_latest_by = 'created_at'
        ordering = ['-created_at', 'author']


class Comments(models.Model):

    article = models.ForeignKey(Article, related_name='comments', on_delete=models.CASCADE)

    author = models.ForeignKey(User, on_delete=models.CASCADE)

    body = models.TextField(null=False, blank=False, error_messages={"required": "You cannot submit without a comment."})

    created_at = models.DateTimeField(auto_created=True, auto_now=False, default=timezone.now)

    def __str__(self):
        """
        :return: string
        """
        return self.body

    class Meta:
        get_latest_by = 'created_at'
        ordering = ['-created_at']


class Replies(models.Model):

    comment = models.ForeignKey(Comments, related_name='replies', on_delete=models.CASCADE)

    author = models.ForeignKey(User, related_name='replies',  on_delete=models.CASCADE)

    content = models.TextField(null=False, blank=False,
                            error_messages={"required": "You cannot submit without a reply."})

    created_at = models.DateTimeField(auto_created=True, auto_now=False, default=timezone.now)

    def __str__(self):
        """
        :return: string
        """
        return self.content

    class Meta:
        get_latest_by = 'created_at'
        ordering = ['-created_at']

我怎样才能为 UPDATING 和 CREATING 制定目标逻辑以避免该错误。

【问题讨论】:

    标签: python django django-rest-framework


    【解决方案1】:

    将字段设置为只读不会解决您的问题。即使默认情况下将其设置为 read_only 模型也无法在数据库中存储空白值。如果您在创建对象时未创建作者和评论,则以允许空白和空值的方式修改您的模型。

    author = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True)
    

    【讨论】:

    • 这个可行,但问题是,在作者和评论上插入空值,无法引用。
    • 如果您在该表中有有效的作者或评论条目,您可以在插入时指定它。如果您创建新文章,可能还没有 cmets。所以存储空白意味着没有相关的对象。
    • 我明白你的意思,但我的所有回复确实有评论。在我发布回复后,我在 URL 中传递了 cmets 的 Id 以引用它。
    • 那么我怎么能说清楚,因为当我看我的模型时,我发现一切都很好,会介意,帮助我解决这个问题。
    • 问题是,当我删除序列化程序中字段上的 read_only 时,commentauthor 可用,但是当我添加它们时comment_idauthor_id 变为 null
    猜你喜欢
    • 2017-03-05
    • 2019-06-07
    • 2013-07-10
    • 2016-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-16
    • 1970-01-01
    相关资源
    最近更新 更多