DALF assumes that the related model must have .id
field.
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 [email protected] # 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
Filter working as intended?
N/A
Linux 5.15.0-130-generic #140-Ubuntu SMP Wed Dec 18 17:59:53 UTC 2024 x86_64
)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
Pay now to fund the work behind this issue.
Get updates on progress being made.
Maintainer is rewarded once the issue is completed.
You're funding impactful open source efforts
You want to contribute to this effort
You want to get funding like this too