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, когда он станет доступен.

Другие вопросы по тегам