get_queryset()缺少1个必需的位置参数:“ country_id”

时间:2019-02-21 13:28:14

标签: python django django-models django-views django-urls

例如,我有一个国家/地区列表,它们都有自己的网址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.

3 个答案:

答案 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)

您需要确保从get_queryset方法返回queryset,而不是object