特定模型的Django ModelForm动态字段选择

时间:2019-11-08 08:32:19

标签: django django-models django-forms

我正在尝试根据动态project_id来选择“ cost_name”字段选择。

models.py

class ProjectCost(models.Model):
    project_name = models.ForeignKey(ProjectName, on_delete=models.CASCADE,null=True)
    cost_name = models.CharField('Cost Name', max_length=50)
    total_budget = models.DecimalField('Total Budget', max_digits=9,decimal_places=2)

forms.py

class CreateCostForm(forms.ModelForm):

    def __init__(self,project_id,*args, **kwargs):

        super(CreateCostForm, self).__init__(*args, **kwargs)
        self.fields['cost_name'].queryset = ProjectCost.objects.filter(project_name_id=project_id)

    class meta:
        model = ProjectCost

当我将project_id的值硬编码为:

self.fields['project_name'].queryset = ProjectCost.objects.filter(project_name_id=4) or 
ProjectCost.objects.filter(project_name_id= 8),

我在表单上获得了正确的过滤选项。那么如何使 project_id 动态?

我尝试过:

def __init__(self, *args, **kwargs):
    project_id = kwargs.pop('project_id', None)
    super(CreateCostForm, self).__init__(*args, **kwargs)
    self.fields['cost_name'].queryset = ProjectCost.objects.filter(project_name_id=project_id)

但这将为“ project_id”的值返回“无”。关于如何解决此问题的任何想法?

谢谢。

1 个答案:

答案 0 :(得分:1)

当您从CreateView进行子分类时,将有一个方法调用get_form_kwargs()将数据从视图发送到表单。像这样覆盖它:

class YourView(CreateView):
     ...
     def get_form_kwargs(self, *args, **kwargs):
         form_kwargs = super(YourView, self).get_form_kwargs(*args, **kwargs)
         form_kwargs['project_id'] = self.kwargs.get('project_id')  # assuming you send the project_id through url ie path('project/<int:project_id>/create/', YourView.as_view())
         return form_kwargs

通过这种方式,您将以project_id的形式获取数据:

Class CreateCostForm(forms.ModelForm):
     def __init__(self, *args, **kwargs):
        project_id = kwargs.pop('project_id', None)