作者:是非涩味_943 | 来源:互联网 | 2022-12-03 16:20
我正在使用Django detailview。最初,我使用URL模式
url(r'^todo/details/(?P[\d]+)', views.todoDetailView.as_view(), name='detail_todo'),
我的看法是
class todoDetailView(DetailView):
model = models.todo
工作正常。
在第二种情况下,我的网址是
url(r'^todo/details/(?P[\d]+)', views.todoDetailView.as_view(), name='detail_todo'),
这次,我修改了观点
class todoDetailView(DetailView):
model = models.todo
# context_object_name = 'todo_detail'
def get_object(self, **kwargs):
print(kwargs)
return models.todo.objects.get(id=self.kwargs['id'])
效果很好,我将第二种情况修改为
class todoDetailView(DetailView):
model = models.todo
# context_object_name = 'todo_detail'
def get_queryset(self):
return models.todo.objects.get(id=self.kwargs['id'])
然后我得到一个错误,
通用详细信息视图todoDetailView必须使用对象pk或子弹调用。
我知道没有提供适当的子弹或pk。因此,最初我添加了get_object()(它可以工作),但是get_queryset()不起作用。他们的工作有什么区别?
而且,如果用户仅根据这些信息获取详细信息,我在StackOverflow上读到
可以使用
slug_field = 'param_name'
slug_url_kwarg = 'param_name'
链接- 通用详细信息视图ProfileView必须使用对象pk或子弹调用
任何人都可以向我解释get_object()和get_queryset()的实际工作方式(如果可能的话,还要get_slug_field())
以及条款slug_field
和slug_url_kwarg
提前致谢
1> Ariel..:
get_object
返回一个对象(模型的实例),而get_queryset
返回一个QuerySet对象,该对象映射到模型的一组可能的多个实例。对于DetailView
(或实际上是从继承的任何类)SingleObjectMixin
,的目的get_queryset
是限制您尝试从中获取实例的对象集。
如果要显示实例的详细信息,则必须以某种方式告诉Django如何获取该实例。默认情况下,如错误消息所示,Django会调用在URL中get_object
查找pk
或slug
参数的方法。在第一个示例中,在pk
URL中,Django设法自动获取了实例,因此一切正常。在第二个示例中,您覆盖了get_object
方法,并手动使用id
传递的as参数来获取对象,该对象也起作用。但是,在第三个示例中,您没有提供get_object
方法,因此Django执行了默认方法。SingleObjectMixin的默认get_object
方法找不到pk或子弹,因此失败了。
有多种解决方法:
1.
pk
在网址中使用
最简单的方法是简单地使用您在第一个示例中提供的代码。我不知道您为什么不满意,这很好。如果您不满意,请详细解释原因。
2.覆写
get_object
这是您提供的第二个解决方案。这是多余的,因为如果您使用正确的选项正确配置了视图(如以下替代方法所示),则Django会为您获取对象。
3.提供
pk_url_kwarg
选项
如果id
出于某些原因确实要在URL中使用,可以通过指定以下pk_url_kwarg
选项在视图中表明这一点:
class todoDetailView(DetailView):
model = models.todo
pk_url_kwarg = 'id'
4.提供
slug_field
和
slug_url_kwarg
选项[请勿这样做]
这是一个糟糕的解决方案,因为您并不是真正地使用一个子进程,而是一个id,但是从理论上讲它应该可以工作。基本上,您将“愚弄” Django来使用该id
字段,就好像它是一个ug。我之所以仅提及它,是因为您在问题中明确询问了这些选项。
class todoDetailView(DetailView):
model = models.todo
slug_field = 'id'
slug_url_kwarg = 'id'
关于您的get_queryset
方法:在您的示例中,它甚至没有被执行,但是无论如何它都被破坏了,因为它返回的是一个单独的对象而不是一个查询集(就是objects.get
这样)。我的猜测是您可能根本不需要自定义get_queryset
方法。例如,如果您有一个复杂的权限系统,其中不同的用户只能访问todo
对象的不同子集,那么这将很有用,我认为情况并非如此。当前,如果提供此get_queryset
方法,则即使其他所有配置均正确,也会出现错误。可能是AttributeError,它表示queryset
对象没有属性filter
(因为它实际上是一个todo
对象,而不是Django期望的QuerySet对象)。