Skip to main content
 首页 » 编程设计

python之Django formset之如何为 modelformset 中的每个表单提供不同的查询集

2024年12月31日27lvdongjie

我有一个模型表单 - ClinicallyReportedSample,它链接到一个样本模型。

我正在尝试为 ClinicallyReportedSample 创建一个表单集,其中基于 Sample 的查询集,显示特定数量的表单,以便用户可以添加数据。

目前,Sample 模型有条目,但 ClinicallyReportedSample 模型完全是空的:

模型:

class Sample(models.Model): 
 
    request_number = models.PositiveIntegerField() 
    year = models.PositiveIntegerField() 
 
 
    class Meta: 
        db_table = "sample" 
        unique_together = (('request_number', 'year'),) 
 
    def __str__(self): 
        return("%s/%s" %(self.request_number, self.year)) 
 
 
 
class ClinicallyReportedSample(models.Model): 
 
    sample_id = models.ForeignKey(Sample, 
                                on_delete=models.CASCADE, 
                                db_column='sample_id') 
 
 
    reported = models.BooleanField(default=False) 
    evidence = models.TextField(null=True, blank=True) 
 
    ... other fields ... 
 
    class Meta: 
        db_table = "clinically_reported_sample" 
        unique_together = (('sample_id'),) 
 
    def __str__(self): 
        clinically_reported_sample = str(self.sample_id) 
        return(clinically_reported_sample) 

我想要一个表单集中的 ClinicallyReportedSample 模型表单,它与 Sample 模型的查询集相关。

例如,pk 为 1、2 和 3 的样本对象:

表单.py:

class BaseCRSFormSet(BaseModelFormSet): 
    def __init__(self, *args, **kwargs): 
        super().__init__(*args, **kwargs) 
        # self.queryset = ClinicallyReportedVariant.objects.none() 
 
 
class CRSForm(forms.ModelForm): 
 
    class Meta: 
        model = ClinicallyReportedSample 
        fields = ('sample_id', 'evidence',) 
 
    def __init__(self, *args, **kwargs): 
        super(CRSForm, self).__init__(*args, **kwargs) 

所以我尝试在我的表单集中使用查询集来做到这一点

views.py:

def get(self, request, *args, **kwargs): 
 
 
    sample_obj = Sample.objects.filter(id__in=[1, 2, 3]) 
 
    formset = modelformset_factory( 
                ClinicallyReportedSample, 
                form=self.crsform, 
                formset=BaseCRSFormSet, 
                extra=3, 
            ) 
 
 
    formset = formset(queryset=sample_obj) 

但这显示为三种形式,对于所有 Sample 对象,查询集不起作用。这是解决此问题的正确方法吗?

请您参考如下方法:

您需要将默认的示例查询集设置为无:

class CRSForm(forms.ModelForm): 
 
    class Meta: 
        model = ClinicallyReportedSample 
        fields = ('sample_id', 'evidence',) 
 
    sample_id = forms.ModelChoiceField(queryset=Sample.objects.none()) 
 
    def __init__(self, *args, **kwargs): 
        super(CRSForm, self).__init__(*args, **kwargs) 

然后当你创建一个表单集实例时,像这样手动分配查询集:

def get(self, request, *args, **kwargs): 
 
    sample_obj = Sample.objects.filter(id__in=[1, 2, 3]) 
 
    formset = modelformset_factory( 
                ClinicallyReportedSample, 
                form=self.crsform, 
                formset=BaseCRSFormSet, 
                extra=3, 
            ) 
 
 
    formset = formset(queryset=sample_obj) 
 
    for form in formset: 
        form.fields['sample_id'].queryset = sample_obj 

请注意,您还必须在 POST 函数中手动设置查询集,否则它将无法验证。