【问题标题】:How to filter many to many field in django form如何以 django 形式过滤多对多字段
【发布时间】:2021-07-10 10:35:41
【问题描述】:

我有一个模型选举,它有一个与候选模型有多对多关系的“候选人”字段和一个与区域模型有一对多关系的“区域”字段。此外,Candidate 模型也有一个 region 字段,它与 Region 模型也有一对多的关系。

现在我创建了模型选举的模型形式。我的问题是如何过滤特定区域的候选人

这是我的模型和表格

 class Region(models.Model):
    region_name = models.CharField(max_length=200, null=True)
    region_id = models.CharField(max_length=20, null=True, unique=True)

    def __str__(self):
        return self.region_name

 class Candidate(models.Model):
    region = models.ForeignKey(Region, null=True, on_delete=models.SET_NULL)
    name = models.CharField(max_length=200, null=True)
    party_name = models.CharField(max_length=200, null=True)
    candidate_id = models.CharField(max_length=10, null=True, unique=True)

    def __str__(self):
        return self.name

 class Election(models.Model):
    admin = models.ForeignKey(Admin, null=True, on_delete=models.SET_NULL)
    region_name = models.ForeignKey(Region, null=True, on_delete=models.SET_NULL)
    region_id = models.CharField(max_length=200, null=True)
    date_created = models.DateField(null=True)
    candidates = models.ManyToManyField(Candidate)
    winner = models.CharField(max_length=200, blank=True) 

 class NewElectionForm(forms.ModelForm):
    class Meta:
        model = Election
        exclude = ['winner']
    def __init__ (self, *args, **kwargs):
        super(NewElectionForm, self).__init__(*args, **kwargs)
        self.fields["candidates"].widget = forms.widgets.CheckboxSelectMultiple()
                #below query is for testing
        #region = Region.objects.get(region_name='Mumbai')
        self.fields["candidates"].queryset = region.candidate_set.all()

每个地区都有一个管理员将发布此表单。由于 region_name 在这里是可变的,我无法运行 region.candidate_set 查询 如果上述方法不可行,还有其他解决方案吗?

【问题讨论】:

  • 太宽泛了,REGION 变量是从哪里来的?是登录用户所在的地区,还是访问者提供的?

标签: django django-models django-forms django-queryset


【解决方案1】:
Candidate.objects.filter(region__region_name="Mumbai")

以上查询将为您提供 region="Mumbai" 的所有候选人

【讨论】:

    【解决方案2】:

    由于表单将由区域管理员发布,并且 Election 模型具有 Admin 的外键,因此您可以按管理员过滤选举,从而为您提供来自管理员区域的候选人

    在呈现此表单的 VIEW 中,添加一个方法

        class YourView(...):
            .....
    
            # This inserts 'admin' into kwargs of the form BEFORE it's loaded
            def get_form_kwargs(self):
                kwargs = super(YourView, self).get_form_kwargs()
                kwargs['admin'] = self.request.user
                return kwargs
    
    
        class NewElectionForm(forms.ModelForm):
            class Meta:
                model = Election
                exclude = ['winner']
            def __init__ (self, *args, **kwargs):
    
                #instanciate the admin variable that you inserted into kwargs
                admin = kwargs.pop('admin')
                super(NewElectionForm, self).__init__(*args, **kwargs)
                self.fields["candidates"].widget = forms.widgets.CheckboxSelectMultiple()
                self.fields["candidates"].queryset = Election.objects.filter(admin=admin)
    

    或 如果您的 Admin 模型有 Region 字段

            def get_form_kwargs(self):
                kwargs = super(YourView, self).get_form_kwargs()
                kwargs['region'] = self.request.user.region
                return kwargs
    

    然后查询候选模型为

        class NewElectionForm(forms.ModelForm):
            class Meta:
                model = Election
                exclude = ['winner']
            def __init__ (self, *args, **kwargs):
    
                #instanciate the region variable that you inserted into kwargs
                region = kwargs.pop('region')
                super(NewElectionForm, self).__init__(*args, **kwargs)
                self.fields["candidates"].widget = forms.widgets.CheckboxSelectMultiple()
                self.fields["candidates"].queryset = Candidate.objects.filter(region=region)
    

    【讨论】:

      猜你喜欢
      • 2018-06-07
      • 2015-07-18
      • 1970-01-01
      • 2020-03-20
      • 2016-12-13
      • 2013-01-22
      • 2014-05-25
      • 2018-05-25
      • 2018-10-19
      相关资源
      最近更新 更多