Django使用DetailView创建联系页面报错:需在URLconf传入pk或slug
解决Django中DetailView用于联系页时缺少pk/slug的报错
问题原因
DetailView的设计初衷是展示单个模型实例的详情,它默认会从URL中提取pk或slug参数,以此查询对应的数据库对象。你的URL路由没有传递这些参数,所以框架抛出了Generic detail view MyContactsView must be called with either an object pk or a slug in the URLconf.错误。而且你的代码已经在get_context_data里手动获取了最新的Contacts对象,完全没必要用DetailView。
解决方案
方案1:改用TemplateView(推荐)
TemplateView专门用于渲染简单动态或静态页面,更适合联系页这类不需要处理单个模型实例详情的场景,逻辑更贴合需求:
from django.views.generic.base import TemplateView from typing import Any, Dict class MyContactsView(TemplateView): template_name = 'contacts/contact.html' def get_context_data(self, **kwargs: Any) -> Dict[str, Any]: """Generate the data to be displayed on the page.""" context = super().get_context_data(**kwargs) main_banner = MainBanner.objects.order_by('-id').last() context['main_banner'] = main_banner contacts = Contacts.objects.order_by('-id').last() context['contacts'] = contacts return context
URL配置保持原样即可,无需修改。
方案2:若坚持用DetailView,重写get_object方法
如果一定要保留DetailView,可以重写get_object方法,手动指定要获取的对象,绕过URL参数的要求:
class MyContactsView(DetailView): model = Contacts template_name = 'contacts/contact.html' def get_object(self, queryset=None): # 直接返回最新的Contacts对象,无需从URL提取参数 return Contacts.objects.order_by('-id').last() def get_context_data(self, **kwargs: Any) -> Dict[str, Any]: """Generate the data to be displayed on the page.""" context = super().get_context_data(**kwargs) main_banner = MainBanner.objects.order_by('-id').last() context['main_banner'] = main_banner # 注:DetailView会自动将get_object返回的对象存入context,键为模型名小写(即'contacts'),所以下面这行可删除 # context['contacts'] = contacts return context
内容的提问来源于stack exchange,提问作者Vladimir Shevchenko
相关产品推荐
相关产品推荐

