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

Django DetailView with custom identifier (not pk): Field 'id' expected a number but got 'XQ1wfrpiLVAkjAUL'

我正在使用 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

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

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

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

我该如何解决这个问题?

pk_url_kwarg 属性仅供 Django 使用以从视图 kwargs 中获取正确的 kwarg。最后,Django 仍会生成 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)