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

get_queryset() missing 1 required positional argument: 'country_id'

例如,我有一份他们都拥有的国家/地区列表 url 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.

发生这种情况是因为您的 urls.py 没有传递 views.py 位置参数 country_id。您可以这样修复它:

path('<str:country_id>', views.CityOverview.as_view())

现在,如果用户导航到 /al 和 /ad,此路径将起作用,并且字符串将作为位置参数传递到您的 CityOverview 视图。有关详细信息,请参阅 URL 调度程序上的 Django Docs

只需从 kwargs 得到 country_id。对于 get_queryset,您需要 return queryset 但不是单个对象。所以使用 filter 而不是 get.

def get_queryset(self, *args, **kwargs):
    country_id = self.kwargs['country_id']
    return City.objects.filter(country=country_id)

有几个地方需要改,先从模型说起:

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)

您需要确保return一个queryset from the get_queryset method, not an object