farhan0581 / django-admin-autocomplete-filter

A simple Django app to render list filters in django admin using autocomplete widget.
GNU General Public License v3.0
351 stars 75 forks source link

FieldError on creating filters for models with custom primary keys #69

Open Hanimir-san opened 3 years ago

Hanimir-san commented 3 years ago

Hi!

We're using admin autocomplete filters in a project and for most cases it works fine, we do however have some models for which the primary key is not 'id' which is causing an error when trying to generate filters for them. The model and filter in question are:

models.py

class Region(models.Model):
    region = models.CharField(
        max_length=15,
        default='',
        primary_key=True,
        verbose_name=_('ISO 3166-2'),
        help_text=_('Please enter a region using its ISO3166 2-letter-code (e.g. DE).')
    )
    region_3 = models.CharField(max_length=255, verbose_name=_('ISO 3166-3'), blank=True, null=True, help_text=_('Please enter an ISO 3166 3-letter code'))
    region_name_local = models.CharField(max_length=255, verbose_name=_('Region name (local)'), blank=True, null=True, help_text=_('Please enter the region name in local language'))
    region_name_en = models.CharField(max_length=255, verbose_name=_('Region name (en)'), blank=True, null=True, help_text=_('Please enter the region name in English'))
    internet = models.CharField(max_length=25, verbose_name=_('Internet'), blank=True, null=True, help_text=_('Please enter the internet domain'))
    active = models.BooleanField(verbose_name=_('Active'), default=False, blank=True, db_index=True, null=True, help_text=_('Please select whether the region is active. If not it will be removed from select lists in other contexts.'))
    cr_date = models.DateTimeField(_('Creation date'), auto_now_add=True)
    cr_user = models.ForeignKey(User, verbose_name=_('Creation user'), related_name='%(class)s_creation_user',
                                editable=False, null=True, blank=True, on_delete=models.PROTECT)
    mod_date = models.DateTimeField(_('Modification date'), auto_now=True)
    mod_user = models.ForeignKey(User, verbose_name=_('Modification user'), related_name='%(class)s_modification_user',
                                 editable=False, null=True, blank=True, on_delete=models.PROTECT)
admin.py

class UsageRegionFilter(AutocompleteFilter):
    title = _('region')  # display title
    field_name = 'region'  # name of the foreign key field

The primary key of the model in question is 'region'. Looking at the code in the repo I tried various things without success (like setting parameter_name or field_pk). Here's the full traceback:

currently using Django 3.2.5

Traceback (most recent call last):
  File "/Users/dev/.pyenv/versions/3.8.0/envs/venv380/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/Users/dev/.pyenv/versions/3.8.0/envs/venv380/lib/python3.8/site-packages/django/core/handlers/base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
    return callback(request, *args, **kwargs)
  File "/Users/dev/.pyenv/versions/3.8.0/envs/venv380/lib/python3.8/site-packages/django/contrib/admin/options.py", line 616, in wrapper
    return self.admin_site.admin_view(view)(*args, **kwargs)
  File "/Users/dev/.pyenv/versions/3.8.0/envs/venv380/lib/python3.8/site-packages/django/utils/decorators.py", line 130, in _wrapped_view
    response = view_func(request, *args, **kwargs)
  File "/Users/dev/.pyenv/versions/3.8.0/envs/venv380/lib/python3.8/site-packages/django/views/decorators/cache.py", line 44, in _wrapped_view_func
    response = view_func(request, *args, **kwargs)
  File "/Users/dev/.pyenv/versions/3.8.0/envs/venv380/lib/python3.8/site-packages/django/contrib/admin/sites.py", line 232, in inner
    return view(request, *args, **kwargs)
  File "/Users/dev/.pyenv/versions/3.8.0/envs/venv380/lib/python3.8/site-packages/reversion/admin.py", line 230, in changelist_view
    return super().changelist_view(request, context)
  File "/Users/dev/.pyenv/versions/3.8.0/envs/venv380/lib/python3.8/site-packages/django/utils/decorators.py", line 43, in _wrapper
    return bound_method(*args, **kwargs)
  File "/Users/dev/.pyenv/versions/3.8.0/envs/venv380/lib/python3.8/site-packages/django/utils/decorators.py", line 130, in _wrapped_view
    response = view_func(request, *args, **kwargs)
  File "/Users/dev/.pyenv/versions/3.8.0/envs/venv380/lib/python3.8/site-packages/django/contrib/admin/options.py", line 1697, in changelist_view
    cl = self.get_changelist_instance(request)
  File "/Users/dev/.pyenv/versions/3.8.0/envs/venv380/lib/python3.8/site-packages/django/contrib/admin/options.py", line 736, in get_changelist_instance
    return ChangeList(
  File "/Users/dev/.pyenv/versions/3.8.0/envs/venv380/lib/python3.8/site-packages/django/contrib/admin/views/main.py", line 99, in __init__
    self.queryset = self.get_queryset(request)
  File "/Users/dev/.pyenv/versions/3.8.0/envs/venv380/lib/python3.8/site-packages/django/contrib/admin/views/main.py", line 450, in get_queryset
    ) = self.get_filters(request)
  File "/Users/dev/.pyenv/versions/3.8.0/envs/venv380/lib/python3.8/site-packages/django/contrib/admin/views/main.py", line 137, in get_filters
    spec = list_filter(request, lookup_params, self.model, self.model_admin)
  File "/Users/dev/.pyenv/versions/3.8.0/envs/venv380/lib/python3.8/site-packages/admin_auto_filters/filters.py", line 72, in __init__
    self.rendered_widget = field.widget.render(
  File "/Users/dev/.pyenv/versions/3.8.0/envs/venv380/lib/python3.8/site-packages/django/forms/widgets.py", line 246, in render
    context = self.get_context(name, value, attrs)
  File "/Users/dev/.pyenv/versions/3.8.0/envs/venv380/lib/python3.8/site-packages/django/forms/widgets.py", line 683, in get_context
    context = super().get_context(name, value, attrs)
  File "/Users/dev/.pyenv/versions/3.8.0/envs/venv380/lib/python3.8/site-packages/django/forms/widgets.py", line 644, in get_context
    context['widget']['optgroups'] = self.optgroups(name, context['widget']['value'], attrs)
  File "/Users/dev/.pyenv/versions/3.8.0/envs/venv380/lib/python3.8/site-packages/django/contrib/admin/widgets.py", line 436, in optgroups
    for obj in self.choices.queryset.using(self.db).filter(**{'%s__in' % to_field_name: selected_choices})
  File "/Users/dev/.pyenv/versions/3.8.0/envs/venv380/lib/python3.8/site-packages/django/db/models/query.py", line 941, in filter
    return self._filter_or_exclude(False, args, kwargs)
  File "/Users/dev/.pyenv/versions/3.8.0/envs/venv380/lib/python3.8/site-packages/django/db/models/query.py", line 961, in _filter_or_exclude
    clone._filter_or_exclude_inplace(negate, args, kwargs)
  File "/Users/dev/.pyenv/versions/3.8.0/envs/venv380/lib/python3.8/site-packages/django/db/models/query.py", line 968, in _filter_or_exclude_inplace
    self._query.add_q(Q(*args, **kwargs))
  File "/Users/dev/.pyenv/versions/3.8.0/envs/venv380/lib/python3.8/site-packages/django/db/models/sql/query.py", line 1393, in add_q
    clause, _ = self._add_q(q_object, self.used_aliases)
  File "/Users/dev/.pyenv/versions/3.8.0/envs/venv380/lib/python3.8/site-packages/django/db/models/sql/query.py", line 1412, in _add_q
    child_clause, needed_inner = self.build_filter(
  File "/Users/dev/.pyenv/versions/3.8.0/envs/venv380/lib/python3.8/site-packages/django/db/models/sql/query.py", line 1286, in build_filter
    lookups, parts, reffed_expression = self.solve_lookup_type(arg)
  File "/Users/dev/.pyenv/versions/3.8.0/envs/venv380/lib/python3.8/site-packages/django/db/models/sql/query.py", line 1112, in solve_lookup_type
    _, field, _, lookup_parts = self.names_to_path(lookup_splitted, self.get_meta())
  File "/Users/dev/.pyenv/versions/3.8.0/envs/venv380/lib/python3.8/site-packages/django/db/models/sql/query.py", line 1539, in names_to_path
    raise FieldError("Cannot resolve keyword '%s' into field. "
django.core.exceptions.FieldError: Cannot resolve keyword 'id' into field. Choices are: active, asset, cr_date, cr_user, cr_user_id, extractionconfig, internet, mod_date, mod_user, mod_user_id, posts, region, region_3, region_name_en, region_name_local, tu, tu2, usage, userpreferences