Django 3.1 с использованием обновления Tagulous из-за ошибки администратора
Я использую django v3.1 и библиотеку django-tagulous для тегов моделей. Он отлично работает над добавлением. Но выдает ошибку ниже при попытке обновить / изменить. Я очень запутался, что здесь происходит! TBN, Django v3.1 больше не имеет библиотеки django.utils.six, поэтому мне приходится использовать шесть сторонних библиотек.
Internal Server Error: /admin/blog/pages/2/change/
Traceback (most recent call last):
File "/home/toki/workplace/django-jazzmin-test/djazzenv/lib/python3.6/site-packages/django/db/models/options.py", line 575, in get_field
return self.fields_map[field_name]
KeyError: 'pk'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/toki/workplace/django-jazzmin-test/djazzenv/lib/python3.6/site-packages/tagulous/models/tagged.py", line 72, in _split_kwargs
field = model._meta.get_field(field_name)
File "/home/toki/workplace/django-jazzmin-test/djazzenv/lib/python3.6/site-packages/django/db/models/options.py", line 577, in get_field
raise FieldDoesNotExist("%s has no field named '%s'" % (self.object_name, field_name))
django.core.exceptions.FieldDoesNotExist: Pages has no field named 'pk'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/toki/workplace/django-jazzmin-test/djazzenv/lib/python3.6/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/home/toki/workplace/django-jazzmin-test/djazzenv/lib/python3.6/site-packages/django/core/handlers/base.py", line 179, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/toki/workplace/django-jazzmin-test/djazzenv/lib/python3.6/site-packages/django/contrib/admin/options.py", line 614, in wrapper
return self.admin_site.admin_view(view)(*args, **kwargs)
File "/home/toki/workplace/django-jazzmin-test/djazzenv/lib/python3.6/site-packages/django/utils/decorators.py", line 130, in _wrapped_view
response = view_func(request, *args, **kwargs)
File "/home/toki/workplace/django-jazzmin-test/djazzenv/lib/python3.6/site-packages/django/views/decorators/cache.py", line 44, in _wrapped_view_func
response = view_func(request, *args, **kwargs)
File "/home/toki/workplace/django-jazzmin-test/djazzenv/lib/python3.6/site-packages/django/contrib/admin/sites.py", line 233, in inner
return view(request, *args, **kwargs)
File "/home/toki/workplace/django-jazzmin-test/djazzenv/lib/python3.6/site-packages/django/contrib/admin/options.py", line 1656, in change_view
return self.changeform_view(request, object_id, form_url, extra_context)
File "/home/toki/workplace/django-jazzmin-test/djazzenv/lib/python3.6/site-packages/django/utils/decorators.py", line 43, in _wrapper
return bound_method(*args, **kwargs)
File "/home/toki/workplace/django-jazzmin-test/djazzenv/lib/python3.6/site-packages/django/utils/decorators.py", line 130, in _wrapped_view
response = view_func(request, *args, **kwargs)
File "/home/toki/workplace/django-jazzmin-test/djazzenv/lib/python3.6/site-packages/django/contrib/admin/options.py", line 1534, in changeform_view
return self._changeform_view(request, object_id, form_url, extra_context)
File "/home/toki/workplace/django-jazzmin-test/djazzenv/lib/python3.6/site-packages/django/contrib/admin/options.py", line 1573, in _changeform_view
form_validated = form.is_valid()
File "/home/toki/workplace/django-jazzmin-test/djazzenv/lib/python3.6/site-packages/django/forms/forms.py", line 177, in is_valid
return self.is_bound and not self.errors
File "/home/toki/workplace/django-jazzmin-test/djazzenv/lib/python3.6/site-packages/django/forms/forms.py", line 172, in errors
self.full_clean()
File "/home/toki/workplace/django-jazzmin-test/djazzenv/lib/python3.6/site-packages/django/forms/forms.py", line 376, in full_clean
self._post_clean()
File "/home/toki/workplace/django-jazzmin-test/djazzenv/lib/python3.6/site-packages/django/forms/models.py", line 411, in _post_clean
self.validate_unique()
File "/home/toki/workplace/django-jazzmin-test/djazzenv/lib/python3.6/site-packages/django/forms/models.py", line 420, in validate_unique
self.instance.validate_unique(exclude=exclude)
File "/home/toki/workplace/django-jazzmin-test/djazzenv/lib/python3.6/site-packages/django/db/models/base.py", line 1006, in validate_unique
errors = self._perform_unique_checks(unique_checks)
File "/home/toki/workplace/django-jazzmin-test/djazzenv/lib/python3.6/site-packages/django/db/models/base.py", line 1108, in _perform_unique_checks
qs = qs.exclude(pk=model_class_pk)
File "/home/toki/workplace/django-jazzmin-test/djazzenv/lib/python3.6/site-packages/django/db/models/query.py", line 950, in exclude
return self._filter_or_exclude(True, *args, **kwargs)
File "/home/toki/workplace/django-jazzmin-test/djazzenv/lib/python3.6/site-packages/tagulous/models/tagged.py", line 118, in _filter_or_exclude
self.model, kwargs, lookups=True, with_fields=True
File "/home/toki/workplace/django-jazzmin-test/djazzenv/lib/python3.6/site-packages/tagulous/models/tagged.py", line 73, in _split_kwargs
except models.fields.FieldDoesNotExist:
AttributeError: module 'django.db.models.fields' has no attribute 'FieldDoesNotExist'
[23/Aug/2020 11:55:49] "POST /admin/blog/pages/2/change/ HTTP/1.1" 500 20203
Также вот моя модель -
class Pages(BaseEntityBasicAbstract, HitCountMixin):
"""
Pages added from the dashboard with content
"""
PAGE_STATUS = (
('draft', _('Draft')),
('public', _('Public')),
('private', _('Private'))
)
CONTENT_OPTIONS = (
('only_content', _('Only show content on the page.')),
('only_sections', _('Only show sections on the page.')),
('both_content_sections', _('Show both contents & sections.')),
)
language = models.CharField(max_length=10, choices=settings.LANGUAGES, default='en',
db_index=True)
title = models.CharField(max_length=255, null=True, blank=True, verbose_name=_('Title'),
help_text=_('Provide title of the page.'))
sub_caption = models.TextField(max_length=255, verbose_name=_('Summery'),
null=True, blank=True,
help_text=_('Provide sub-caption for the page.'))
url = models.CharField(max_length=255, unique=True, verbose_name=_('URL/Slug/Link'),
help_text=_('Provide an unique string without whitespaces.'))
content = HTMLField(null=True, blank=True, verbose_name=_('Content'),
help_text=_('Provide content for the page.'))
featured_image = models.FileField(upload_to=FilePrefix('pages/'), null=True, blank=True,
verbose_name=_('Featured Image'),
help_text=_('Provide a featured image for the page.'))
image_caption = models.TextField(max_length=255, null=True, blank=True,
verbose_name=_('Image Caption'),
help_text=_('Provide caption for featured image.'))
template = models.CharField(max_length=255, null=True, blank=True,
verbose_name=_('Template'),
help_text=_('Select a custom template for the page.'))
status = models.CharField(max_length=10, choices=PAGE_STATUS, default='public',
verbose_name=_('Page Status'),
help_text=_('Only public pages can be seen on front end.'))
is_home = models.BooleanField(default=False, verbose_name=_('Set this page as home.'))
content_options = models.CharField(max_length=100, choices=CONTENT_OPTIONS,
default='both_content_sections',
verbose_name=_('Content Options'),
help_text=_('Select how content & sections are '
'arranged.'))
is_default = models.BooleanField(default=False)
seo_words = tagulous.models.TagField(
blank=True,
force_lowercase=True,
max_count=50,
verbose_name=_('Meta Tags'),
help_text=_('Provide meta tags separated by commas for page SEO.')
)
menu_items = GenericRelation(MenuItems, object_id_field='id', null=True, blank=True,
related_query_name='page_as_menu')
hit_count_generic = GenericRelation(HitCount, object_id_field='object_pk',
related_query_name='page_hit_count')
created_by = models.ForeignKey(User, related_name='page_created_by',
on_delete=models.SET_NULL, null=True, blank=True,
verbose_name=_('Created By'))
updated_by = models.ForeignKey(User, related_name='page_updated_by',
on_delete=models.SET_NULL, null=True, blank=True,
verbose_name=_('Last Updated By'))
deleted_by = models.ForeignKey(User, related_name='page_deleted_by',
on_delete=models.SET_NULL, null=True, blank=True,
verbose_name=_('Deleted By'))
def __str__(self):
return self.title
def get_absolute_url(self):
url = reverse('frontend:page', kwargs={'slug': self.url})
return url
def save(self, *args, **kwargs):
instance = None
self.created_by = get_current_user()
self.language = get_current_request().LANGUAGE_CODE
if self.pk:
instance = self.pk
self.updated_by = get_current_user()
if not self.url:
self.url = slugify_final(self.title, Pages, instance)
else:
self.url = slugify_final(self.url, Pages, instance)
if self.is_home:
# select all other active items
qs = type(self).objects.filter(is_home=True)
# except self (if self already exists)
if self.pk:
qs = qs.exclude(pk=self.pk)
# and deactive them
qs.update(is_home=False)
if not self.is_home and self.pk:
qs = type(self).objects.filter(is_home=True).exclude(pk=self.pk)
print(qs)
if not qs.exists():
def_home = type(self).objects.filter(
is_default=True,
url__icontains='def-home'
).first()
if def_home:
def_home.is_home = True
def_home.save()
super(Pages, self).save(*args, **kwargs)
class Meta:
verbose_name = _('Page')
verbose_name_plural = _('Pages')
1 ответ
В настоящее время Tagulous поддерживает только Django 2.2; Поддержка Django 3.1 будет в следующем выпуске. Для меня это приоритет, но это проект свободного времени, и в наши дни я не получаю от него особого внимания.
Вы можете следить за ходом работы по обновлению здесь: https://github.com/radiac/django-tagulous/issues/85, хотя некоторые люди там говорили о краткосрочном исправлении, пока я не выпущу следующую версию.
Тем не менее, в следующих двух выпусках будет много исправлений и оптимизаций, поэтому я бы рекомендовал вернуться к выпуску pypi, когда он станет доступен.