Django访问品牌详情页报get()缺少self/request参数TypeError求解
这个报错的核心触发点是URL路由配置错误,加上你的视图文件里有3处笔误和逻辑错误,全部修正后即可正常运行。
访问
/brand/5时抛出异常:TypeError at /brand/5 get() missing 2 required positional arguments: 'self' and 'request'
1. 先解决直接触发报错的路由问题
Django类视图不能直接把类对象传给路由,必须调用类自带的as_view()方法完成实例化,你当前的urls.py里品牌详情页的路由大概率是错误写法:
# 错误写法,直接传类会触发你遇到的参数缺失报错 path('brand/<int:pk>', views.Brand)
修改为正确写法即可解决当前的TypeError:
# 给路由加个name方便后续反向解析 path('brand/<int:pk>', views.Brand.as_view(), name='brand_detail')
2. 修复views.py里的笔误和逻辑问题
你贴的views.py里有3处会导致后续页面报错的问题:
- 视图类和模型类同名
Brand,非常容易引发引用冲突,建议视图类加后缀区分 Brands列表视图的super()方法传参错误,传入了模型类Brand而非当前视图类- 品牌详情视图的模板路径属性拼写错误,把
template_name写成了tempal_name,少了一个字母t,会导致模板找不到的报错 - 两个类视图都重复写了内置类视图已经自动实现的查询逻辑,属于冗余代码,可以删掉
修正后的views.py代码:
from django.shortcuts import render, get_object_or_404 from .models import Product,ProductCategory, Brand from django.views import generic class BrandListView(generic.ListView): model = Brand template_name = 'productcatalog/brands.html' def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) # ListView默认已经把查询到的品牌列表存在object_list变量里,这行可按需保留 context['brands'] = Brand.objects.all() return context class BrandDetailView(generic.DetailView): model = Brand # 修正拼写错误 template_name = 'productcatalog/brand_details.html' def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) # DetailView会自动根据URL里的pk查询对应的Brand对象,存在self.object和context的brand/object变量里,不需要手动调用get_object_or_404 return context
对应改完视图类名之后,urls.py里的路由也要同步把引用的类名改成BrandListView和BrandDetailView。
3. 修复models.py里的小问题
你在Brand模型里写了get_absolute_url方法,但是没有导入reverse,而且返回的路径不对,补全导入、修正路由即可:
from django.db import models from django.urls import reverse # 补这行导入 class Brand(models.Model): name = models.CharField(max_length=300,blank=True) def __str__(self): return self.name def get_absolute_url(self): # 对应之前给品牌详情路由设的name,传入当前实例的pk return reverse('brand_detail', kwargs={'pk': self.pk})
全部改完之后重启Django服务,再访问品牌详情页就可以正常运行了。
内容的提问来源于stack exchange,提问作者Arnold Schwartzkopf
相关产品推荐
相关产品推荐

