Python 更新时生成只读字段,但不在ModelSerializer的CREATE方法中
我是python新手,我想在Django中创建一个API,这是我面临的挑战之一,我正在尝试使更新端点和创建端点工作 当我在更新过程中忽略了一些必填字段时,它可以工作,但CREATE方法不能工作,它会带来以下错误消息:Python 更新时生成只读字段,但不在ModelSerializer的CREATE方法中,python,django,django-rest-framework,Python,Django,Django Rest Framework,我是python新手,我想在Django中创建一个API,这是我面临的挑战之一,我正在尝试使更新端点和创建端点工作 当我在更新过程中忽略了一些必填字段时,它可以工作,但CREATE方法不能工作,它会带来以下错误消息: IntegrityError at /api/articles/comment/4/replies/ null value in column "author_id" violates not-null constraint DETAIL: Failing row contains
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)
当我删除序列化程序中的只读时,问题会转到更新端点,如postman中所示:
{
"comment": [
"This field is required."
],
"author": [
"This field is required."
]
}
以下是我的代码片段:
serializers.py中的我的序列化程序
class RepliesSerializer(serializers.ModelSerializer):
class Meta:
model = Replies
fields = '__all__'
read_only_fields = ('comment', 'author',)
"""
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']
查看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中的model类
class RepliesSerializer(serializers.ModelSerializer):
class Meta:
model = Replies
fields = '__all__'
read_only_fields = ('comment', 'author',)
"""
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']
我如何制定更新和创建的目标逻辑以避免该错误。仅读取字段并不能解决您的问题。即使在默认情况下将其设置为只读,模型也不能在数据库中存储空白值。如果在创建对象时未创建作者和注释,请修改模型,使其允许空白和空值
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)
author = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True)
这一个可行,但问题是,在author和comment上插入空值,这无法作为引用。如果该表中有有效的author或comment条目,则可以在插入时指定它。如果您创建了一篇新文章,可能还没有评论。所以存储空白意味着没有相关对象。我明白你的意思,但是我的案例所有回复都有评论。在我发布回复后,我在URL中传递评论Id以引用它。因此,我如何才能明确这一点,因为当我查看我的模型时,我发现一切都很好,请介意,帮我解决这个问题。问题是,当我删除序列化器中字段的只读时,评论和作者都可用,但是当我添加它们时,注释id和作者id变为空