Skip to content

[BUG] Does not support models with PK not named "id" #16

@sterliakov

Description

@sterliakov

Describe the bug

var queryParam = fieldName + "__id__exact";

DALF assumes that the related model must have .id field.

To Reproduce

Start from the test project in tests/testproject of this repository.

cd $(mktemp -d)
git clone https://github.com/vigo/django-admin-list-filter
cd django-admin-list-filter
cd test/testproject
python -m venv venv
. ./venv/bin/activate
pip install 'django==5.1.5' ../..
vim testapp/models.py
# Edit the models file to use `uuid` as PK, see full contents below
./manage makemigrations && ./manage.py migrate
./manage.py createsuperuser --username demo --email demo@demo.com  # Provide any password
./manage.py shell -c 'from testapp.models import Category; Category.objects.create(name="Foo")'
./manage.py runserver

Now visit the live server URL with /admin appended in any browser, sign in and navigate to the Post model (http://localhost:8000/admin/testapp/post/). Try to select "Foo" category in the filter. Observe url change to .../?e=1, which indicates incorrect lookup fields. Try to select it again to observe a "database error" message.

Here's the full content of new models.py that can be copy&paste'd directly:

import uuid

from django.conf import settings
from django.db import models


class Category(models.Model):
    uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField(max_length=255)

    def __str__(self):
        return self.name


class Tag(models.Model):
    uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField(max_length=255)

    def __str__(self):
        return self.name


class AudienceChoices(models.TextChoices):
    BEGINNER = 'beginner', 'Beginer'
    INTERMEDIATE = 'intermediate', 'Intermediate'
    PRO = 'pro', 'Pro'


class Post(models.Model):
    uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    author = models.ForeignKey(
        to=settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name='posts',
    )
    category = models.ForeignKey(
        to='Category',
        on_delete=models.CASCADE,
        related_name='posts',
    )
    tags = models.ManyToManyField(to='Tag', blank=True)
    audience = models.CharField(
        max_length=100,
        choices=AudienceChoices.choices,
        default=AudienceChoices.BEGINNER,
    )

    title = models.CharField(max_length=255)

    def __str__(self):
        return self.title

Expected behavior

Filter working as intended?

Screenshots

N/A

Environment (please complete the following information):

  • OS: Ubuntu 22.04 (Linux 5.15.0-130-generic #140-Ubuntu SMP Wed Dec 18 17:59:53 UTC 2024 x86_64)
  • CPU: Intel(R) Core(TM) i3-8145U CPU @ 2.10GHz
  • Python version: [e.g., 3.11] 3.11
  • Django version: [e.g., 5.0.2] 5.1.5
  • Django Admin List Filter package version: [e.g., 0.1.0]: 0.2.6
  • Browser Vendor and version: [e.g., Firefox 126.0 (64-bit)] any browser

Additional context

This bug is trivial to fix: replace __id__exact with __pk__exact in the linked JS file (there are two occurrences, both have to be replaced). This is likely the only place to change. django provides pk attribute/field for all models that resolves to its primary key field (see e.g. here).

I'm ready to submit a PR with this change if you're interested and the project is still maintained. For now, I patch the bug in Dockerfile:

RUN sed -i -e 's/__id__exact/__pk__exact/g' /.venv/lib/python3.11/site-packages/dalf/static/admin/js/django_admin_list_filter.js

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions