使用模型的值创建 Django 表单

use model's value to create a Django form

我有一个模型如下:

class BloodTestType(models.Model):
    type = models.CharField(max_length=200)
    def __str__(self):
        return str(self.type)

class BloodParameters(models.Model):
    type = models.ForeignKey(BloodTestType, on_delete=models.CASCADE)
    parameter = models.CharField(max_length=200)
    minimum_value = models.FloatField()
    maximum_value = models.FloatField()
    unit = models.CharField(max_length=200)
    required = models.BooleanField(default=True)
    GENDER_CHOICES =  [
    ('B', 'Both'),
    ('M', 'Male'),
    ('F', 'Female'),
    ]
    gender = models.CharField(max_length = 100,choices = GENDER_CHOICES,default = 'B')

    def __str__(self):
        return str(self.type) + ' ' + str(self.parameter)

考虑 BloodParameters 模型有 3 个类型为“1”的参数

我想创建一个包含这 3 个参数作为输入字段的 Django 表单,但该表单加载时显示为空白。我正在我的表单文件中的这些行上尝试一些东西:

class BloodReportCBCIronForm(forms.Form):
    cbc_iron_parameters = BloodParameters.objects.filter(type = 1)
    print('asd')
    print(cbc_iron_parameters.__dict__)
    for each in cbc_iron_parameters:
        each.parameter = forms.CharField(label = each.parameter,max_length = 80,required = True,)

您希望向表单动态添加字段,而执行此操作的位置在表单的 __init__ 方法中。像这样:

from django import forms
from django.utils.text import slugify


class BloodReportCBCIronForm(forms.Form):
    def __init__(self, type, *args, **kwargs):
        """
        Initializes a form with a dynamic set of fields, based upon objects fetched from the database.        
        :param type: integer ID of a BloogTestType object 
        :param args: 
        :param kwargs: 
        """
        cbc_iron_parameters = BloodParameters.objects.filter(type__id=type)

        for each in cbc_iron_parameters:
            # Safety-check here, in case the each.parameter value contains spaces or symbols.
            field_name = slugify(each.parameter)
            # Add a field to the self.base_fields dictionary. Note that this doesn't deal 
            # with the scenario where there are multiple parameters with the same name.
            self.base_fields[field_name] = forms.CharField(label=each.parameter, max_length=80, required=True)

        # super() will now create fields based off of whatever you added to the self.base_fields dictionary.
        super().__init__(*args, **kwargs)

然后要初始化和使用表单,您需要执行如下操作:

form = BloodReportCBCIronForm(type=1)