python - @admin.register 装饰器在 Django 中导致 (admin.###) 错误
问题描述
使用@admin.register
装饰器会产生 (admin.###) 错误。我最初怀疑它与这个问题有关,但是在摆弄这个问题时。我发现只需切换到使用即可admin.site.register
修复它。什么时候用@admin.register
,什么时候用admin.site.register
呢?我有这些模型
### models.py
from django.db import models
from django.utils import timezone
from django.urls import reverse
from django.contrib.auth.models import User
class PublishedManager(models.Manager):
def get_queryset(self):
return super(PublishedManager,
self).get_queryset().filter(
status='published'
)
class Post(models.Model):
objects = models.Manager() #default manager
published = PublishedManager() # custom manager
STATUS_CHOICES = (
('draft', 'Draft'),
('published', 'Published'),
)
title = models.CharField(max_length=250)
slug = models.SlugField(max_length=250,
unique_for_date='publish')
author = models.ForeignKey(User,
on_delete=models.CASCADE,
related_name='blog_posts')
body = models.TextField()
publish = models.DateTimeField(default=timezone.now)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
status = models.CharField(max_length=10,
choices=STATUS_CHOICES,
default='draft')
class Meta:
ordering = ('-publish',)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('blog:post_detail',
args=[
self.publish.year,
self.publish.month,
self.publish.day,
self.slug
])
class Comment(models.Model):
post = models.ForeignKey(Post,
on_delete=models.CASCADE,
related_name='comments')
name = models.CharField(max_length=80)
email = models.EmailField()
body = models.TextField()
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
active = models.BooleanField(default=True)
class Meta:
ordering = ('created',)
def __str__(self):
return f'Comment by {self.name} on {self.post}'
还有这些
### admin.py
from django.contrib import admin
from .models import Post, Comment
# Register your models here.
admin.site.register(Post)
admin.site.register(Comment)
class PostAdmin(admin.ModelAdmin):
list_display = ('title','slug','author','publish','status')
list_filter = ('status', 'created', 'publish', 'author')
search_fields = ('title', 'body')
# prepopulate the slug field with the input of the title field
prepopulated_fields = {'slug': ('title',)}
raw_id_fields = ('author',)
date_hierarchy = 'publish'
ordering = ('author','status', 'publish')
class CommentAdmin(admin.ModelAdmin):
list_display = ('name', 'email', 'post', 'created', 'active')
list_filter = ('active', 'created', 'updated')
search_fields = ('name', 'email', 'body')
当我使用 decorator@admin.register
时,出现以下错误:
Exception in thread django-main-thread:
Traceback (most recent call last):
File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py", line 926, in _bootstrap_inner
self.run()
File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "/Users/admin/django-samples/blog/venv/lib/python3.7/site-packages/django/utils/autoreload.py", line 53, in wrapper
fn(*args, **kwargs)
File "/Users/admin/django-samples/blog/venv/lib/python3.7/site-packages/django/core/management/commands/runserver.py", line 117, in inner_run
self.check(display_num_errors=True)
File "/Users/admin/django-samples/blog/venv/lib/python3.7/site-packages/django/core/management/base.py", line 441, in check
raise SystemCheckError(msg)
django.core.management.base.SystemCheckError: SystemCheckError: System check identified some issues:
ERRORS:
<class 'blog.admin.PostAdmin'>: (admin.E002) The value of 'raw_id_fields[0]' refers to 'author', which is not an attribute of 'blog.Comment'.
<class 'blog.admin.PostAdmin'>: (admin.E027) The value of 'prepopulated_fields' refers to 'slug', which is not an attribute of 'blog.Comment'.
<class 'blog.admin.PostAdmin'>: (admin.E030) The value of 'prepopulated_fields["slug"][0]' refers to 'title', which is not an attribute of 'blog.Comment'.
<class 'blog.admin.PostAdmin'>: (admin.E033) The value of 'ordering[0]' refers to 'author', which is not an attribute of 'blog.Comment'.
<class 'blog.admin.PostAdmin'>: (admin.E033) The value of 'ordering[1]' refers to 'status', which is not an attribute of 'blog.Comment'.
<class 'blog.admin.PostAdmin'>: (admin.E033) The value of 'ordering[2]' refers to 'publish', which is not an attribute of 'blog.Comment'.
<class 'blog.admin.PostAdmin'>: (admin.E108) The value of 'list_display[0]' refers to 'title', which is not a callable, an attribute of 'PostAdmin', or an attribute or method on 'blog.Comment'.
<class 'blog.admin.PostAdmin'>: (admin.E108) The value of 'list_display[1]' refers to 'slug', which is not a callable, an attribute of 'PostAdmin', or an attribute or method on 'blog.Comment'.
<class 'blog.admin.PostAdmin'>: (admin.E108) The value of 'list_display[2]' refers to 'author', which is not a callable, an attribute of 'PostAdmin', or an attribute or method on 'blog.Comment'.
<class 'blog.admin.PostAdmin'>: (admin.E108) The value of 'list_display[3]' refers to 'publish', which is not a callable, an attribute of 'PostAdmin', or an attribute or method on 'blog.Comment'.
<class 'blog.admin.PostAdmin'>: (admin.E108) The value of 'list_display[4]' refers to 'status', which is not a callable, an attribute of 'PostAdmin', or an attribute or method on 'blog.Comment'.
<class 'blog.admin.PostAdmin'>: (admin.E116) The value of 'list_filter[0]' refers to 'status', which does not refer to a Field.
<class 'blog.admin.PostAdmin'>: (admin.E116) The value of 'list_filter[2]' refers to 'publish', which does not refer to a Field.
<class 'blog.admin.PostAdmin'>: (admin.E116) The value of 'list_filter[3]' refers to 'author', which does not refer to a Field.
<class 'blog.admin.PostAdmin'>: (admin.E127) The value of 'date_hierarchy' refers to 'publish', which does not refer to a Field.
切换到admin.site.register
这样使用
admin.site.register(Post)
admin.site.register(Comment)
修复它。
现在我想知道使用有什么问题
@admin.register(Post)
@admin.register(Comment)
解决方案
1) 这是一个用于注册你的 ModelAdmin 类的装饰器
from django.contrib import admin
from .models import Author
@admin.register(Author)
class AuthorAdmin(admin.ModelAdmin):
pass
2) 这是注册 ModelAdmin 类的第二种方式。
from django.contrib import admin
from .models import Author
class AuthorAdmin(admin.ModelAdmin):
pass
admin.site.register(Author, AuthorAdmin)
3)当您不使用 ModelAdmin 时,您应该像这样注册
from django.contrib import admin
from .models import Author
admin.site.register(Author)