Django Admin注册Collection模型时触发TypeError: 'NoneType'不可调用
Django Admin注册Collection模型报错排查
问题描述
我尝试在Django Admin页面注册Collection模型,模型代码如下:
class Collection(models.Model): title = models.CharField(max_length=255) featured_product = models.ForeignKey( 'Product', on_delete=models.SET_NULL, null=True, related_name='+') def __str__(self): return self.title class Meta: ordering = ['title']
admin.py中的代码:
@admin.site.register(models.Collection) class CollectionAdmin(admin.ModelAdmin): list_display = ['title', 'products_count'] def products_count(self, collection): return collection.products_count def get_queryset(self, request): return super().get_queryset(request).annotate(products_count=Count)
但注册该模型后出现错误,其他模型注册正常,报错栈信息如下:
C:\Users\jonas_6xnnk8f\PycharmProjects\storefront\store\admin.py changed, reloading. Watching for file changes with StatReloader Exception in thread django-main-thread: Traceback (most recent call last): File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python39_64\lib\threading.py", line 980, in _bootstrap_inner self.run() File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python39_64\lib\threading.py", line 917, in run self._target(*self._args, **self._kwargs) File "C:\Users\jonas_6xnnk8f\PycharmProjects\djangoproject\venv\lib\site-packages\django\utils\autoreload.py", line 64, in wrapper fn(*args, **kwargs) File "C:\Users\jonas_6xnnk8f\PycharmProjects\djangoproject\venv\lib\site-packages\django\core\management\commands\runserver.py", line 125, in inner_run autoreload.raise_last_exception() File "C:\Users\jonas_6xnnk8f\PycharmProjects\djangoproject\venv\lib\site-packages\django\utils\autoreload.py", line 87, in raise_last_exception raise _exception[1] File "C:\Users\jonas_6xnnk8f\PycharmProjects\djangoproject\venv\lib\site-packages\django\core\management\__init__.py", line 394, in execute autoreload.check_errors(django.setup)() File "C:\Users\jonas_6xnnk8f\PycharmProjects\djangoproject\venv\lib\site-packages\django\utils\autoreload.py", line 64, in wrapper fn(*args, **kwargs) File "C:\Users\jonas_6xnnk8f\PycharmProjects\djangoproject\venv\lib\site-packages\django\__init__.py", line 24, in setup apps.populate(settings.INSTALLED_APPS) File "C:\Users\jonas_6xnnk8f\PycharmProjects\djangoproject\venv\lib\site-packages\django\apps\registry.py", line 124, in populate app_config.ready() File "C:\Users\jonas_6xnnk8f\PycharmProjects\djangoproject\venv\lib\site-packages\django\contrib\admin\apps.py", line 27, in ready self.module.autodiscover() File "C:\Users\jonas_6xnnk8f\PycharmProjects\djangoproject\venv\lib\site-packages\django\contrib\admin\__init__.py", line 50, in autodiscover autodiscover_modules("admin", register_to=site) File "C:\Users\jonas_6xnnk8f\PycharmProjects\djangoproject\venv\lib\site-packages\django\utils\module_loading.py", line 58, in autodiscover_modules import_module("%s.%s" % (app_config.name, module_to_search)) File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python39_64\lib\importlib\__init__.py", line 127, in import_module return _bootstrap._gcd_import(name[level:], package, level) File "<frozen importlib._bootstrap>", line 1030, in _gcd_import File "<frozen importlib._bootstrap>", line 1007, in _find_and_load File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked File "<frozen importlib._bootstrap>", line 680, in _load_unlocked File "<frozen importlib._bootstrap_external>", line 850, in exec_module File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed File "C:\Users\jonas_6xnnk8f\PycharmProjects\storefront\store\admin.py", line 38, in <module> class CollectionAdmin(admin.ModelAdmin): TypeError: 'NoneType' object is not callable
错误原因及修复方案
核心错误点
Count使用不当:- 未正确导入
Count类,需从django.db.models导入该类。 annotate(products_count=Count)中Count缺少必填参数——要统计的关联字段名称,导致无法生成有效的查询注解,触发类型错误。
- 未正确导入
- 装饰器写法(可选优化):
@admin.site.register(models.Collection)是合法写法,但@admin.register(models.Collection)是更简洁的等效写法,两种都可使用,需确保装饰器直接作用在CollectionAdmin类上。
修正后的admin.py代码
from django.contrib import admin from django.db.models import Count from . import models @admin.register(models.Collection) class CollectionAdmin(admin.ModelAdmin): list_display = ['title', 'products_count'] def products_count(self, collection): return collection.products_count def get_queryset(self, request): # 此处的'products'是Product模型中指向Collection的外键对应的反向关联名,需根据实际代码调整 return super().get_queryset(request).annotate( products_count=Count('products') )
额外确认事项
- 确保Product模型中存在指向Collection的外键,例如:
如果class Product(models.Model): # 其他字段... collection = models.ForeignKey(Collection, on_delete=models.CASCADE, related_name='products')related_name设置为其他值,需同步修改Count方法中的参数。
内容的提问来源于stack exchange,提问作者JonasAurelius
相关产品推荐
相关产品推荐

