FieldError:不能为 Post 模型表单指定“已创建”,因为它是不可编辑的字段
Posted
技术标签:
【中文标题】FieldError:不能为 Post 模型表单指定“已创建”,因为它是不可编辑的字段【英文标题】:FieldError: 'created' cannot be specified for Post model form as it is a non-editable field 【发布时间】:2020-10-22 23:24:16 【问题描述】:Django 3.0.8
admin.py
class PostAdmin(admin.ModelAdmin):
list_display = ("id", "title", 'category',)
def get_fields(self, request, obj=None):
fields = [a_field.name for a_field in self.model._meta.fields]
return fields
def get_readonly_fields(self, request, obj):
readonly_fields = self.readonly_fields
if obj:
if obj.already_published and (not request.user.has_perm('posts.change_already_puclished')):
readonly_fields = READONLY_FIELDS_AFTER_PUBLISHING
return readonly_fields
追溯
Exception Type: FieldError
Exception Value:
'created' cannot be specified for Post model form as it is a non-editable field. Check fields/fieldsets/exclude attributes of class PostAdmin.
本地变量
Variable Value
change
False
defaults
'exclude': None,
'fields': ['id',
'comment',
'title',
'slug',
'description',
'body',
'draft',
'already_published',
'featured_image',
'category',
'excerpt',
'h1',
'author',
'created',
'updated',
'sidebar',
'keywords',
'lsi',
'google_indexed',
'google_first_indexed',
'yandex_indexed',
'yandex_first_indexed'],
'form': <class 'django.forms.widgets.ModelForm'>,
'formfield_callback': functools.partial(<bound method BaseModelAdmin.formfield_for_dbfield of <posts.admin.PostAdmin object at 0x7f1d596e3820>>, request=<WSGIRequest: GET '/admin/posts/post/add/'>)
exclude
None
excluded
None
fields
['id',
'comment',
'title',
'slug',
'description',
'body',
'draft',
'already_published',
'featured_image',
'category',
'excerpt',
'h1',
'author',
'created',
'updated',
'sidebar',
'keywords',
'lsi',
'google_indexed',
'google_first_indexed',
'yandex_indexed',
'yandex_first_indexed']
form
<class 'django.forms.widgets.ModelForm'>
kwargs
new_attrs
'declared_fields':
obj
None
readonly_fields
()
request
<WSGIRequest: GET '/admin/posts/post/add/'>
self
<posts.admin.PostAdmin object at 0x7f1d596e3820>
同图:
我使用超级用户和没有 change_already_pucliished 权限的用户尝试此代码。
-
超级用户:尝试添加或更改帖子时,出现错误。
普通用户:添加帖子正常,没有错误。但添加新姿势会导致此错误。
编辑
class Post(DraftMixin,
TitleMixin,
TagMixin,
SlugMixin,
DescriptionMixin,
CommentMixin,
FeaturedImageMixin,
BodyMixin,
models.Model):
category = models.ForeignKey(Category,
on_delete=models.PROTECT,
verbose_name="Категория")
excerpt = models.TextField(default=True,
blank=True,
verbose_name="Выдержка") # A text associated to a Post. Most of the time, it is used as the Post summary.
h1 = models.CharField(max_length=500,
blank=True,
default="",
verbose_name="H1")
author = models.ForeignKey(Author,
blank=True,
null=True,
on_delete=models.PROTECT,
related_name='blog_posts',
verbose_name="Автор")
created = models.DateField(auto_now_add=True,
verbose_name="Дата создания")
updated = models.DateField(auto_now=True,
verbose_name="Дата обновления")
sidebar = models.ForeignKey(Sidebar,
null=True,
blank=True,
on_delete=models.PROTECT,
verbose_name="Сайдбар")
keywords = models.TextField(blank=True, default="", verbose_name="Ключевые слова")
lsi = models.TextField(blank=True, default="", verbose_name="LSI")
google_indexed = models.BooleanField(verbose_name="Индексировано Google",
default=False)
google_first_indexed = models.DateField(blank=True,
null=True,
verbose_name="Дата первой индексации Google")
yandex_indexed = models.BooleanField(verbose_name="Индексировано Яндекс",
default=False)
yandex_first_indexed = models.DateField(blank=True,
null=True,
verbose_name="Дата первой индексации Яндексом")
class Meta:
ordering = ('-created',)
verbose_name = "Статья"
verbose_name_plural = "Статьи"
permissions = [
("change_already_puclished", 'Может менять статус "Уже опубликовано"'),
]
【问题讨论】:
您能否提供您的 Post 模型的代码 【参考方案1】:问题是由这个定义引起的:
created = models.DateField(auto_now_add=True,
verbose_name="Дата создания")
auto_now_add 使 Django 无法编辑它。所以不能将其指定为可编辑的表单域。
您需要将其指定为只读字段。见:Django admin: How to display a field that is marked as editable=False' in the model?
【讨论】:
【参考方案2】:如果您将auto_now_add
设置为True
,则默认情况下该字段将变为不可编辑(editable=False
),Django 将自动处理该字段。此外,auto_now=True
将导致对任何更改的覆盖,因为当您在实例上调用 save()
时,它将更新该字段。
您可以通过将这些字段添加到readonly_fields
来添加要在表单中显示的字段,但您不能添加/编辑它们。现在你要么必须删除 auto_now_add
和 auto_now
并为它们提供你的价值,要么你应该让 Django 为你做这件事。
Django 文档:DateField.auto_now_add
【讨论】:
以上是关于FieldError:不能为 Post 模型表单指定“已创建”,因为它是不可编辑的字段的主要内容,如果未能解决你的问题,请参考以下文章