我有以下型号:

class Product(models.Model):
    active = models.BooleanField(default=True)
    name = models.CharField(max_length=40, unique=True)
    acronym = models.CharField(max_length=3, unique=True)
    bool1_name = models.CharField(max_length=60, blank=True, null=True)
    bool1_default = models.BooleanField(default=False)
    int1_name = models.CharField(max_length=60, blank=True, null=True)
    int1_default = models.IntegerField(blank=True, null=True)
    float1_name = models.CharField(max_length=60, blank=True, null=True)
    float1_default = models.FloatField(blank=True, null=True)
    date1_name = models.CharField(max_length=60, blank=True, null=True)

class ProductData(models.Model):
    created = models.DateTimeField(default=datetime.now)
    created_by = models.ForeignKey(User)
    item = models.ManyToManyField(Item)
    bool1_val = models.BooleanField(default=False)
    int1_val = models.IntegerField(blank=True, null=True)
    float1_val = models.FloatField(blank=True, null=True)
    date1_val = models.DateField(blank=True, null=True)

class Item(models.Model):
    product = models.ForeignKey(Product)
    business = models.ForeignKey(Business)

我把以下数据输入数据库:
# pseudo code

Product(1,'Toothpaste','TP','Is the toothpaste white?',1,,,'Weight',1,)
Product(1,'Milk','MLK',,,,,'Litres',2,'Best Before')

我希望能够基于ProductData中定义的变量(create-a-form-based-on-the-values-from-another-table)为Product构建一个表单。我想要这样的东西:
class ProductDataForm(ModelForm):

    def __init__(self,p,*args,**kwargs):
        super(ProductDataForm, self).__init__(*args, **kwargs)
        # if the values isn't set in the product
        if p.bool1_name is None:
            # hide the input
            self.fields['bool1_val'].widget = forms.CharField(required=False)
        else:
            # else make sure the name the field name is the product name
            self.fields['bool1_val'].widget = forms.BooleanField(label=p.bool1_name)

...

但我在将Product的实例传递到ProductDataForm时遇到问题。其他人说我可以使用BaseModelFormSet,但这方面的文献很粗略,我不确定如何应用它。
编辑
如果我创建了一个数组,其中包含了我不想在ProductDataForm的in I T中显示的所有字段,那么如何将这些字段传递给Meta类的exclude。就像这样:
class ProductDataForm(ModelForm):

    def __init__(self,p,*args,**kwargs):
        super(ProductDataForm, self).__init__(*args, **kwargs)
        tempExclude = []
        if not p.bool1_name:
            tempExclude.append('bool1_val')
        else:
            self.fields['bool1_val'].label = p.bool1_name

        self.Meta.exclude = tempExclude

    class Meta:
        model = ProductData
        exclude = []

编辑
我现在试图将要排除的字段存储在setting.py文件中,如下所示:
# settings.py
SUBITEM_EXCLUDE_FIELDS = ['dave']

# views.py
def new_product_data_view(request,product='0'):
    try:
        i_fpKEY = int(product)
    except ValueError:
        raise Http404()
    if not i_fpKEY:
        t_fp = Product.objects.filter(active=1).order_by('id')[0]
    else:
        t_fp = Product.objects.get(id=i_fpKEY)
    FieldsToExcludeFromProductDataForm(t_fp)
    print "views.py > PRODUCTDATA_EXCLUDE_FIELDS = "+str(PRODUCTDATA_EXCLUDE_FIELDS)
    siForm = ProductDataForm(t_fp, request.POST, auto_id='si_%s')
    return render_to_response(...)

# middleware.py
def FieldsToExcludeFromProductDataForm(tempFP):
    excludedFields = ['created','created_by','item']
    if not tempFP.bool1_name:
        excludedFields.append('bool1_val')
    if not tempFP.int1_name:
        excludedFields.append('int1_val')
    ...
    for val in excludedFields:
        PRODUCTDATA_EXCLUDE_FIELDS.append(val)
    print "middleware.py > PRODUCTDATA_EXCLUDE_FIELDS = "+str(PRODUCTDATA_EXCLUDE_FIELDS)

# forms.py
class ProductDataForm(ModelForm):

    # Only renames the fields based on whether the product has a name
    # for the field. The exclusion list is made in middleware
    def __init__(self,fp,*args,**kwargs):
        super(ProductDataForm, self).__init__(*args, **kwargs)
        if fp.bool1_name:
            self.fields['bool1_val'].label = fp.bool1_name
        if fp.int1_name:
            self.fields['int1_val'].label = fp.int1_name

    class Meta:

        def __init__(self,*args,**kwargs):
            super(Meta, self).__init__(*args, **kwargs)
            print 'Meta > __init__ > PRODUCTDATA_EXCLUDE_FIELDS = '+str(PRODUCTDATA_EXCLUDE_FIELDS)

        model = ProductData
        print 'Meta > PRODUCTDATA_EXCLUDE_FIELDS = '+str(PRODUCTDATA_EXCLUDE_FIELDS)
        #exclude = PRODUCTDATA_EXCLUDE_FIELDS

但是终端显示Meta类很早就被处理了,因此不能得到新修改的PRODUCTDATA_EXCLUDE_FIELDS
Meta > PRODUCTDATA_EXCLUDE_FIELDS = ['dave']
[11/Jul/2011 15:51:31] "GET /page/profile/1/ HTTP/1.1" 200 11410
middleware.py > PRODUCTDATA_EXCLUDE_FIELDS = ['dave', 'created', 'created_by', 'item', 'bool1_val', 'int1_val']
views.py > PRODUCTDATA_EXCLUDE_FIELDS = ['dave', 'created', 'created_by', 'item', 'bool1_val', 'int1_val']
[11/Jul/2011 15:51:32] "GET /item/new/ HTTP/1.1" 200 5028
[11/Jul/2011 15:51:32] "GET /client/1/ HTTP/1.1" 200 5445
[11/Jul/2011 15:51:32] "GET /client/view/1/ HTTP/1.1" 200 3082

最佳答案

为什么要使用exclude和元类-只需删除要排除的字段:

class ProductDataForm(ModelForm):
     __init__():
         ...
          for field_name in PRODUCTDATA_EXCLUDE_FIELDS:
              del self.fields[field_name]
         ...

也许这不太对,但很简单,而且有效。

关于python - 显示基于另一个表数据的表单元素,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6608185/

10-14 16:06
查看更多