如何解决这个奇怪的错误在管理网站?



我正在做一个国家、地区、县、直辖市和城市的项目。它们中的每一个都有自己的模型,并且模型是使用ModelAdmin注册的。

我的admin.py.

from django.contrib import admin
from .models import Country, Region, County, Municipality, City

@admin.register(Country)
class CountryAdmin(admin.ModelAdmin):
model = Country
list_display = ["name", "continent", "capital", "area", "population", "regions"]
list_filter = ["continent", "area", "population"]
search_fields = ["name", "capital", "description"]

@admin.register(Region)
class RegionAdmin(admin.ModelAdmin):
model = Region
list_display = ["name", "country", "area", "population"]
list_filter = ["country", "area", "population"]
search_fields = ["name", "description"]

@admin.register(County)
class CountyAdmin(admin.ModelAdmin):
model = County
list_display = ["name", "capital", "area", "population", "abbreviation", "verbose_neighbours"]
list_filter = ["region", "area", "population"]
search_fields = ["name", "capital", "description", "abbreviation"]

@admin.register(Municipality)
class MunicipalityAdmin(admin.ModelAdmin):
model = Municipality
list_display = ["name", "county", "area", "population"]
list_filter = ["county", "area", "population"]
search_fields = ["name", "county", "description"]

@admin.register(City)
class CityAdmin(admin.ModelAdmin):
model = City
list_display = ["name", "county", "area", "population"]
list_filter = ["county", "area", "population"]
search_fields = ["name", "description"]

这些是我的模型。

from django.db import models
from django.forms.models import model_to_dict
from django.dispatch import receiver
from django.db.models.signals import pre_save, post_save
from django.utils.translation import gettext_lazy as _

class ModelDiffMixin(object):
"""
A model mixin that tracks model fields' values and provide some useful api
to know what fields have been changed.
"""
def __init__(self, *args, **kwargs):
super(ModelDiffMixin, self).__init__(*args, **kwargs)
self.__initial = self._dict
@property
def fields(self):
return self._meta.fields
@property
def values(self):
field_values = {}
for f in self.fields:
if hasattr(self, f.name) and getattr(self, f.name) not in [None, ""]:
field_values[f.name] = getattr(self, f.name)
return field_values
@property
def local_values(self):
field_values = {}
for f in self.fields:
if hasattr(self, f.name) and getattr(self, f.name) not in [None, ""]:
field_values[f.verbose_name] = getattr(self, f.name)
return field_values
@property
def diff(self):
d1 = self.__initial
d2 = self._dict
diffs = [[k, [v, d2[k]]] for k, v in d1.items() if v != d2[k]]
return dict(diffs)
@property
def has_changed(self):
return bool(self.diff)
@property
def changed_fields(self):
return self.diff.keys()
def get_field_diff(self, field_name):
"""Returns a diff for field if it's changed and None otherwise."""
return self.diff.get(field_name, None)
def save(self, *args, **kwargs):
"""Saves model and set initial state."""
super(ModelDiffMixin, self).save(*args, **kwargs)
self.__initial = self._dict
def update(self, field, new_value):
print(f"{field}: {new_value}")
setattr(self, field, new_value)
self.save()
@property
def _dict(self):
return model_to_dict(self, fields=[field.name for field in self._meta.fields])

class Country(models.Model, ModelDiffMixin):
name = models.CharField(max_length=50, verbose_name=_("numele țării"))
continent = models.CharField(max_length=20, verbose_name=_("continentul"))
capital = models.OneToOneField("Municipality", models.CASCADE, null=True, blank=True, related_name="capital_of_country", verbose_name=_("Capitala"))
description = models.TextField(verbose_name=_("descrierea"))
area = models.IntegerField(verbose_name=_("Suprafața"))
population = models.IntegerField(verbose_name=_("Populația"))
coat_of_arms = models.URLField(verbose_name=_("stema țării"))
class Meta:
verbose_name = _("Țara")
verbose_name_plural = _("Țări")
def __str__(self):
return self.name

class Region(models.Model, ModelDiffMixin):
name = models.CharField(max_length=50, verbose_name=_("Numele regiunei"))
country = models.ForeignKey(Country, on_delete=models.CASCADE, related_name="regions", verbose_name=_("Țara"))
description = models.TextField(verbose_name=_("Descrierea"))
area = models.IntegerField(verbose_name=_("Suprafața"))
population = models.IntegerField(verbose_name=_("Populația"))
coat_of_arms = models.URLField(verbose_name=_("Stema regiunei"))
class Meta:
verbose_name = _("Regiune")
verbose_name_plural = _("Regiuni")
def __str__(self):
return self.name

class County(models.Model, ModelDiffMixin):
name = models.CharField(max_length=50, verbose_name=_("Numele județului"))
capital = models.OneToOneField("Municipality", on_delete=models.PROTECT, null=True, blank=True, related_name="capital_of", verbose_name=_("Reședința"))
region = models.ManyToManyField(Region, related_name="counties", verbose_name=_("Regiunea"))
area = models.IntegerField(verbose_name=_("Suprafața"))
population = models.IntegerField(verbose_name=_("Populația"))
description = models.TextField(verbose_name=_("Descrierea"))
abbreviation = models.CharField(max_length=2, verbose_name=_("Prescurtătura"))
coat_of_arms = models.URLField(verbose_name=_("Stema județului"))
north = models.OneToOneField("self", on_delete=models.SET_NULL, null=True, blank=True, related_name="to_south", verbose_name=_("Către nord"))
northeast = models.OneToOneField("self", on_delete=models.SET_NULL, null=True, blank=True, related_name="to_southwest", verbose_name=_("Către nord-est"))
east = models.OneToOneField("self", on_delete=models.SET_NULL, null=True, blank=True, related_name="to_west", verbose_name=_("Către est"))
southeast = models.OneToOneField("self", on_delete=models.SET_NULL, null=True, blank=True, related_name="to_northwest", verbose_name=_("Către sud-est"))
south = models.OneToOneField("self", on_delete=models.SET_NULL, null=True, blank=True, related_name="to_north", verbose_name=_("Către sud"))
southwest = models.OneToOneField("self", on_delete=models.SET_NULL, null=True, blank=True, related_name="to_northeast", verbose_name=_("Către sud-vest"))
west = models.OneToOneField("self", on_delete=models.SET_NULL, null=True, blank=True, related_name="to_east", verbose_name=_("Către vest"))
northwest = models.OneToOneField("self", on_delete=models.SET_NULL, null=True, blank=True, related_name="to_southeast", verbose_name=_("Către nord-vest"))
class Meta:
verbose_name = _("Județ")
verbose_name_plural = _("Județe")
def __str__(self):
return self.name
@property
def neighbours(self):
directions = ["north", "northeast", "east", "southeast", "south", "southwest", "west", "northwest"]
return directions
@property
def secondary_neighbours(self):
secondary_directions = ["to_north", "to_northeast", "to_east", "to_southeast", "to_south", "to_southwest", "to_west", "to_northwest"] # ["to_south", "to_southwest", "to_west", "to_northwest", "to_north", "to_northeast", "to_east", "to_southeast"]
return secondary_directions
@property
def verbose_neighbours(self):
v_neighbours = {}
for f in self.fields:
if hasattr(self, f.name) and getattr(self, f.name) not in [None, ""] and f.name in self.neighbours:
v_neighbours[f.verbose_name] = getattr(self, f.name)
return v_neighbours
verbose_neighbours.fget.short_description = _("Vecinii")

class Municipality(models.Model, ModelDiffMixin):
name = models.CharField(max_length=50, verbose_name=_("Numele municipiului"))
county = models.ForeignKey(County, on_delete=models.CASCADE, related_name="municipalities", verbose_name=_("Județul"))
area = models.IntegerField(verbose_name=_("Suprafața"))
population = models.IntegerField(verbose_name=_("Populația"))
description = models.TextField(verbose_name=_("Descrierea"))
coat_of_arms = models.URLField(verbose_name=_("Stema orașului"))
class Meta:
verbose_name = _("Municipiu")
verbose_name_plural = _("Municipii")
def __str__(self):
return self.name

class City(models.Model, ModelDiffMixin):
name = models.CharField(max_length=50, verbose_name=_("Numele orașului"))
county = models.ForeignKey(County, on_delete=models.CASCADE, related_name="cities", verbose_name=_("Județul"))
area = models.IntegerField(null=True, blank=True, verbose_name=_("Suprafața"))
population = models.IntegerField(verbose_name=_("Populația"))
description = models.TextField(null=True, blank=True, verbose_name=_("Descrierea"))
class Meta:
verbose_name = _("Oraș")
verbose_name_plural = _("Orașe")
def __str__(self):
return f"{self.name} ({self.county})"

最后,这是当我尝试使用管理站点创建Country模型的新实例或查看创建的国家列表时出现的错误。

Environment:

Request Method: GET
Request URL: http://localhost:1944/admin/counties/country/
Django Version: 3.2.5
Python Version: 3.9.6
Installed Applications:
['django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'counties',
'rest_framework',
'rest_framework.authtoken',
'djoser',
'django_extensions']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']

Template error:
In template D:devpyROvenvlibsite-packagesdjangocontribadmintemplatesadminbase.html, error at line 53
__call__() missing 1 required keyword-only argument: 'manager'
43 :                 {% if site_url %}
44 :                     <a href="{{ site_url }}">{% translate 'View site' %}</a> /
45 :                 {% endif %}
46 :                 {% if user.is_active and user.is_staff %}
47 :                     {% url 'django-admindocs-docroot' as docsroot %}
48 :                     {% if docsroot %}
49 :                         <a href="{{ docsroot }}">{% translate 'Documentation' %}</a> /
50 :                     {% endif %}
51 :                 {% endif %}
52 :                 {% if user.has_usable_password %}
53 :                  <a href="{% url 'adm in:password_change' %}">{% translate 'Change password' %}</a> /
54 :                 {% endif %}
55 :                 <a href="{% url 'admin:logout' %}">{% translate 'Log out' %}</a>
56 :             {% endblock %}
57 :         </div>
58 :         {% endif %}
59 :         {% endblock %}
60 :         {% block nav-global %}{% endblock %}
61 :     </div>
62 :     <!-- END Header -->
63 :     {% block breadcrumbs %}

Traceback (most recent call last):
File "D:devpyROvenvlibsite-packagesdjangocontribadminutils.py", line 265, in lookup_field
f = _get_non_gfk_field(opts, name)
File "D:devpyROvenvlibsite-packagesdjangocontribadminutils.py", line 300, in _get_non_gfk_field
raise FieldDoesNotExist()
During handling of the above exception (), another exception occurred:
File "D:devpyROvenvlibsite-packagesdjangocorehandlersexception.py", line 47, in inner
response = get_response(request)
File "D:devpyROvenvlibsite-packagesdjangocorehandlersbase.py", line 204, in _get_response
response = response.render()
File "D:devpyROvenvlibsite-packagesdjangotemplateresponse.py", line 105, in render
self.content = self.rendered_content
File "D:devpyROvenvlibsite-packagesdjangotemplateresponse.py", line 83, in rendered_content
return template.render(context, self._request)
File "D:devpyROvenvlibsite-packagesdjangotemplatebackendsdjango.py", line 61, in render
return self.template.render(context)
File "D:devpyROvenvlibsite-packagesdjangotemplatebase.py", line 170, in render
return self._render(context)
File "D:devpyROvenvlibsite-packagesdjangotemplatebase.py", line 162, in _render
return self.nodelist.render(context)
File "D:devpyROvenvlibsite-packagesdjangotemplatebase.py", line 938, in render
bit = node.render_annotated(context)
File "D:devpyROvenvlibsite-packagesdjangotemplatebase.py", line 905, in render_annotated
return self.render(context)
File "D:devpyROvenvlibsite-packagesdjangotemplateloader_tags.py", line 150, in render
return compiled_parent._render(context)
File "D:devpyROvenvlibsite-packagesdjangotemplatebase.py", line 162, in _render
return self.nodelist.render(context)
File "D:devpyROvenvlibsite-packagesdjangotemplatebase.py", line 938, in render
bit = node.render_annotated(context)
File "D:devpyROvenvlibsite-packagesdjangotemplatebase.py", line 905, in render_annotated
return self.render(context)
File "D:devpyROvenvlibsite-packagesdjangotemplateloader_tags.py", line 150, in render
return compiled_parent._render(context)
File "D:devpyROvenvlibsite-packagesdjangotemplatebase.py", line 162, in _render
return self.nodelist.render(context)
File "D:devpyROvenvlibsite-packagesdjangotemplatebase.py", line 938, in render
bit = node.render_annotated(context)
File "D:devpyROvenvlibsite-packagesdjangotemplatebase.py", line 905, in render_annotated
return self.render(context)
File "D:devpyROvenvlibsite-packagesdjangotemplateloader_tags.py", line 62, in render
result = block.nodelist.render(context)
File "D:devpyROvenvlibsite-packagesdjangotemplatebase.py", line 938, in render
bit = node.render_annotated(context)
File "D:devpyROvenvlibsite-packagesdjangotemplatebase.py", line 905, in render_annotated
return self.render(context)
File "D:devpyROvenvlibsite-packagesdjangotemplateloader_tags.py", line 62, in render
result = block.nodelist.render(context)
File "D:devpyROvenvlibsite-packagesdjangotemplatebase.py", line 938, in render
bit = node.render_annotated(context)
File "D:devpyROvenvlibsite-packagesdjangotemplatebase.py", line 905, in render_annotated
return self.render(context)
File "D:devpyROvenvlibsite-packagesdjangocontribadmintemplatetagsbase.py", line 33, in render
return super().render(context)
File "D:devpyROvenvlibsite-packagesdjangotemplatelibrary.py", line 214, in render
_dict = self.func(*resolved_args, **resolved_kwargs)
File "D:devpyROvenvlibsite-packagesdjangocontribadmintemplatetagsadmin_list.py", line 308, in result_list
'results': list(results(cl)),
File "D:devpyROvenvlibsite-packagesdjangocontribadmintemplatetagsadmin_list.py", line 284, in results
yield ResultList(None, items_for_result(cl, res, None))
File "D:devpyROvenvlibsite-packagesdjangocontribadmintemplatetagsadmin_list.py", line 275, in __init__
super().__init__(*items)
File "D:devpyROvenvlibsite-packagesdjangocontribadmintemplatetagsadmin_list.py", line 200, in items_for_result
f, attr, value = lookup_field(field_name, result, cl.model_admin)
File "D:devpyROvenvlibsite-packagesdjangocontribadminutils.py", line 278, in lookup_field
value = attr()
Exception Type: TypeError at /admin/counties/country/
Exception Value: __call__() missing 1 required keyword-only argument: 'manager'

我看了一遍又一遍那些文件,但我不明白是什么原因导致这个错误,以及如何摆脱它。请解释一下。:)

也许值得注意的是,Country的实例实际上是创建的。

我认为,你的问题是错误的放置类实例。ModelDiffMixin应放在models.Model之前。

尝试更改:

class Country(models.Model, ModelDiffMixin):
....
# and other models

为:

class Country(ModelDiffMixin, models.Model):
....
# apply the same think to other models

建议:移除你的管理类中的所有model = <ModelName>。Afaik变量不需要,因为您已经在上面注册了它的模型。例句:

@admin.register(Country)
class CountryAdmin(admin.ModelAdmin):
# model = Country   <== no-needed
....

最新更新