# Add native support for CompositePrimaryKey in SingleObjectMixin

**URL:** https://forum.djangoproject.com/t/add-native-support-for-compositeprimarykey-in-singleobjectmixin/38715
**Category:** Django Internals
**Created:** [February 10, 2025, 6:58am UTC](https://forum.djangoproject.com/t/add-native-support-for-compositeprimarykey-in-singleobjectmixin/38715 "2025-02-10T06:58:26Z")
**Posts on this page:** 1
**Showing post:** 1

<div class="post-metadata">

### Author: ![cliff688](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/cliff688/32/22816_2.png) [@cliff688](https://forum.djangoproject.com/u/cliff688)
#### Post date: [February 10, 2025, 6:58am UTC](https://forum.djangoproject.com/t/add-native-support-for-compositeprimarykey-in-singleobjectmixin/38715/1 "2025-02-10T06:58:26Z")

</div>

Howdy!

Now that we have `CompositePrimaryKey` (thank you 😃 !) I wanted to make a proposal to add native support in `SingleObjectMixin`. Currently you can use generic views with CPK models by overriding `get_object` to allow filtering by the two or more path kwargs from the url which correspond to the CPK (assuming you don’t need request information).

If you have many models with `CompositePrimaryKey`s this can be a lot of boilerplate.

The proposed solution is a general mechanism using a new attribute `queryset_filter_kwargs`, which would be a mapping of `path_kwarg` and `field_name`.

```python
# models.py
class Story(models.Model):
    slug = models.SlugField(primary_key=True)
    name = models.CharField()

class Chapter(models.Model):
    pk = models.CompositePrimaryKey("story_id", "number")
    story = models.ForeignKey(
        "Story", on_delete=models.CASCADE, related_name="chapters"
    )
    number = models.PositiveIntegerField()
    title = models.CharField()
    body = models.TextField(blank=True)

```

```py
# views.py
class ChapterDetailView(DetailView):
    model = Chapter
    queryset_filter_kwargs = {
        "story_slug": "story_id", "chapter_number": "number",
    }

```

```py
# urls.py
urlpatterns = [
    path(
        "<slug:story_slug>/chapter/<int:chapter_number>/", ChapterDetailView.as_view(),
    ),
]

```

## Why `queryset_filter_kwargs`?

This is designed as a general attribute rather than something CPK-specific. While brainstorming possible solutions, I realized the problem was fundamentally about enabling queryset filtering based on multiple `url_kwargs`/fields—something I’ve needed to handle frequently.

Also, I couldn’t come up with a good cpk-specific name 😅 (considered allowing `pk_url_kwarg` to be a tuple, but also rejected).

By adopting this approach, we can eliminate the need for redundant `get_queryset()` and `get_object()` overrides, limiting such overrides to cases involving more complex queries or request-specific logic.

In addition, it could potentially also carry the work of `(pk|slug)_url_kwarg` and `(pk|slug)_field`, which seem slated for some change/removal? ([#22724 (Improve SingleObjectMixin) – Django](https://code.djangoproject.com/ticket/22724), [#21898 (SingleObjectMixin should not require slug or pk if queryset is given) – Django](https://code.djangoproject.com/ticket/21898)).

Internally, the implementation could look something like:

```auto
# in get_queryset or get_object
cpk = {
    field_name: self.kwargs.get(path_kwarg)
    for path_kwarg, field_name in self.queryset_filter_kwargs.items()
}
queryset = queryset.filter(**cpk)

```

Would love your thoughts, feedback, or ideas for improvement. Does this sound like a valuable addition to Django?

---

_[View the full topic](https://forum.djangoproject.com/t/add-native-support-for-compositeprimarykey-in-singleobjectmixin/38715)._
