例如,我有一个国家/地区列表,它们都有自己的网址www.example.com/al/。但是当我想按country_id过滤视图时,会出现以下错误:
get_queryset()缺少1个必需的位置参数:“ country_id”
class Country(models.Model):
COUNTRY_CHOICES = (
('Albania', 'Albania'),
('Andorra', 'Andorra'),
# etc. etc.
)
name = models.CharField(max_length=255, choices=COUNTRY_CHOICES, default='Netherlands')
def __str__(self):
return self.name
class City(models.Model):
country = models.ForeignKey(Country, on_delete=models.CASCADE)
name = models.CharField(max_length=250)
def __str__(self):
return self.name
class CityOverview(generic.ListView):
template_name = 'mytemplate.html'
def get_queryset(self, country_id, *args, **kwargs):
return City.objects.get(pk=country_id)
# Albania
path('al', views.CityOverview.as_view(), name='al'),
# Andorra
path('ad', views.CityOverview.as_view(), name='ad'),
# etc. etc.
答案 0 :(得分:2)
之所以发生这种情况,是因为您的urls.py
没有传递views.py
位置参数country_id
。您可以这样修复它:
path('<str:country_id>', views.CityOverview.as_view())
现在,如果用户同时导航到/ al和/ ad,则此路径将起作用,并且该字符串将作为位置参数传递到您的CityOverview
视图。有关更多信息,请参见URL分派器上的Django Docs。
答案 1 :(得分:1)
只需从country_id
获得kwargs
。对于get_queryset
,您需要返回queryset
,但不能返回单个对象。因此,请使用filter
而不是get
。
def get_queryset(self, *args, **kwargs):
country_id = self.kwargs['country_id']
return City.objects.filter(country=country_id)
答案 2 :(得分:1)
您需要在几个地方进行更改,让我们从模型开始:
class Country(models.Model):
COUNTRY_CHOICES = (
('al', 'Albania'), # changing the first value of the touple to country code, which will be stored in DB
('an', 'Andorra'),
# etc. etc.
)
name = models.CharField(max_length=255, choices=COUNTRY_CHOICES, default='nl')
def __str__(self):
return self.name
现在,我们需要更新url路径以获取国家/地区代码的值:
path('<str:country_id>/', views.CityOverview.as_view(), name='city'),
这里,我们使用str:country_id
作为动态路径变量,该变量将接受路径中的字符串,该字符串将作为country_id传递给视图。意思是,无论何时使用localhost:8000/al/
,它都会将值al
作为国家/地区代码传递给视图。
最后,在ListView中获取country_id
的值,并在queryset中使用它。您可以这样做:
class CityOverview(generic.ListView):
template_name = 'mytemplate.html'
def get_queryset(self, *args, **kwargs):
country_id = self.kwargs.get('country_id')
return City.objects.filter(country__name=country_id)