【问题标题】:How to use model objects as choices for django-filter MultipleChoiceFilter如何使用模型对象作为 django-filter MultipleChoiceFilter 的选择
【发布时间】:2020-10-23 09:43:29
【问题描述】:

我正在使用 Django 过滤器,我希望其中一个字段 (supervisor) 是 ChoiceFilter,其中选项是模型中的对象。最有效的方法是什么?我尝试关注this post,但无论我如何更改(当前为cannot unpack non-iterable int object)都会出现错误。

# models.py
class people(models.Model):
    namelast = models.CharField(max_length=100, verbose_name='Last Name')
    namefirst = models.CharField(max_length=100, verbose_name='First Name')
    supervisor = models.ForeignKey('self', blank=True, null=True, on_delete=models.SET_NULL, verbose_name='Supervisor')
    
    def __str__(self):
        return "%s %s" % (self.namefirst, self.namelast)

# filters.py
class office_filter(django_filters.FilterSet):
    supervisor = django_filters.ChoiceFilter(choices=[], lookup_expr='icontains', label='Supervisor')
    # other fields

    class Meta:
        model = people
        fields = ['namelast', 'namefirst', 'supervisor']

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        try:
            self.filters['supervisor'].extra['choices'] = [x for x in
                people.objects.all().values_list('supervisor', flat=True).distinct()]
        except (KeyError, AttributeError):
            pass

我们的目标是让supervisor 字段成为在people 模型中被指定为主管的所有人员的精美菜单。

【问题讨论】:

    标签: python python-3.x django django-filter django-2.x


    【解决方案1】:

    我不是 100% 确定,但你能试试吗?

    [people.objects.get(pk=x[0]) for x in people.objects.all().values_list('supervisor', flat=True).distinct()]
    

    [people.objects.get(id=x[0]) for x in people.objects.all().values_list('supervisor', flat=True).distinct()]
    

    在您提到的链接中,我相信 DatedResource.objects.all().values_list('date', flat=True).distinct()) 返回一个字符串数组

    在您的代码中 people.objects.all().values_list('supervisor', flat=True).distinct() 将返回一个 int 字符串 - 记录的 ID,因为它是外键

    【讨论】:

    • 很高兴知道我发布的链接返回了什么。不幸的是,您的建议的两个版本都给出了错误int object is not subscriptable,所以我尝试了pk=x 并得到了cannot unpack non-iterable people object。整行在 shell 中工作正常,所以我想知道它是否是 django-filter 不喜欢返回的任何列表(在错误消息中不清楚)。
    • 哦,我想我明白了……它必须返回一个元组。 [(people.objects.get(pk=x).id, people.objects.get(pk=x)) for x in people.objects.all().values_list('supervisor', flat=True).distinct() if x is not None] 似乎正在工作。感谢您为我指明正确的方向!
    【解决方案2】:

    Ananya's answer 帮助我正确了解了该语句返回的内容,但是在考虑了错误以及通常如何构造选择列表之后,我意识到我需要它来返回一个元组(而不仅仅是一个值)。这是最终工作的相关代码:

    class office_filter(django_filters.FilterSet):
        supervisor = django_filters.ChoiceFilter(choices=[], label='Supervisor')
        #...
            def __init__(self, *args, **kwargs):
                super().__init__(*args, **kwargs)
                try:
                    self.filters['supervisor'].extra['choices'] = [(people.objects.get(pk=x).id, people.objects.get(pk=x)) for x in people.objects.all().values_list('supervisor', flat=True).distinct() if x is not None]
                except (KeyError, AttributeError):
                    pass
    

    重要的部分是:(people.objects.get(pk=x).id, people.objects.get(pk=x)) 而不仅仅是people.objects.get(pk=x)

    还必须删除过滤器字段中的lookup_expr

    【讨论】:

      猜你喜欢
      • 2021-02-07
      • 2010-10-19
      • 2019-07-15
      • 1970-01-01
      • 1970-01-01
      • 2022-11-11
      • 1970-01-01
      • 2020-05-15
      • 2013-06-22
      相关资源
      最近更新 更多