具有自定义标识符(不是 pk)的 Django DetailView:字段“id”需要一个数字,但得到“XQ1wfrpiLVAkjAUL”

Hom*_*lli 2 django django-class-based-views

我正在使用 Django 3.2

我有一个模型和 GCBV 定义如下:

class Foo(models.Model):
    identifier = models.CharField(max_length=16, db_index=True)
    # ... 

class FooDetailView(DetailView):
    model = Foo
    template_name = 'foo_detail.html'
    pk_url_kwarg = 'identifier'

    # TODO, need to add logic of flagged items etc. to custom Manager and use that instead
    queryset = Foo.objects.filter(is_public=True)

    # # FIXME: This is a hack, just to demo
    # def get_object(self, queryset=None):
    #     objs = Foo.objects.filter(identifier=self.request.GET.get('identifier', 0))
    #     if objs:
    #         return objs[0]
    #     else:
    #         obj = Foo()
    #         return obj
Run Code Online (Sandbox Code Playgroud)

在 urls.py 中,我有以下声明:

path('foo/view/<str:identifier>/', FooDetailView.as_view(), name='foo-detail'),
Run Code Online (Sandbox Code Playgroud)

为什么 Django 需要一个数字(即使我已经明确指定了一个字符串 - 并且还提供了一个pk_url_kwarg参数)?

我该如何解决?

Abd*_*kat 5

pk_url_kwarg属性仅由 Django 使用来从视图 kwargs 中获取正确的 kwarg。最后 Django 仍然会生成(Where )filter的形式。相反,如果您想对自定义字段执行过滤,您应该设置和:queryset.filter(pk=pk)pk = self.kwargs.get(self.pk_url_kwarg)slug_url_kwargslug_field

class FooDetailView(DetailView):
    model = Foo
    template_name = 'foo_detail.html'
    slug_url_kwarg = 'identifier'
    slug_field = 'identifier'

    # TODO, need to add logic of flagged items etc. to custom Manager and use that instead
    queryset = Foo.objects.filter(is_public=True)
Run Code Online (Sandbox Code Playgroud)