获取django表单

时间:2016-09-08 20:32:12

标签: django django-models django-forms

我有以下三种关系:

class Size(models.Model):  
    amount = models.IntegerField(default=0)
    unit = models.CharField(max_length=64)
    created_at = models.DateTimeField(auto_now_add = True)
    updated_at = models.DateTimeField(auto_now = True)

    def __str__(self):  
        return str(self.amount) + ' ' + self.unit + ' size'


class Sku(models.Model):  
    product = models.ForeignKey(Product)
    size = models.ForeignKey(Size)
    style = models.ForeignKey(Style)
    price = models.DecimalField(max_digits=8, decimal_places=2)
    created_at = models.DateTimeField(auto_now_add = True)
    updated_at = models.DateTimeField(auto_now = True)

    def __str__(self):  
        return self.product.name

class ProductImage(models.Model):  
    product = models.ForeignKey(Product)
    title = models.CharField(max_length=128, blank=True, null=True)
    image = models.ImageField(upload_to='products', blank=True, null=True)
    created_at = models.DateTimeField(auto_now_add = True)
    updated_at = models.DateTimeField(auto_now = True)

    def __str__(self):  
        return self.product.name

我希望将所有作为skus外键的大小显示为模型表单中的选项。

我试过了:

class SkuForm(forms.ModelForm):


    def __init__(self, *args, **kwargs):
        product = kwargs.pop('product', None)
        super(SkuForm, self).__init__(*args, **kwargs)

        skus = product.sku_set.all()
        self.fields['size'].queryset = Size.objects.filter(sku__in=skus).values('amount', 'unit').distinct()     

    quantity = forms.IntegerField()

    class Meta:
        model = Sku
        fields = ('size',)

这会在“尺寸”的下拉菜单中显示以下值:

{'amount':5, 'size':'cups'}

我怎样才能让它显示简单:“5杯”?

2 个答案:

答案 0 :(得分:0)

我不确定我是否完全理解您的问题,但我可以告诉您,在设置size字段的查询集时使用.values()是不正确的。

虽然.values()仍然会返回一个查询集,但它不再是模型实例的查询集,而是字典。这不会与ModelChoiceField一起使用,这就是您用作size的表单字段的内容。

您可以通过更改label_from_instance的尺寸字段来获得所需内容。

快速举例:

class Size(models.Model):  
    amount = models.IntegerField(default=0)
    unit = models.CharField(max_length=64)
    created_at = models.DateTimeField(auto_now_add = True)
    updated_at = models.DateTimeField(auto_now = True)

    def __str__(self):  
        return str(self.amount) + ' ' + self.unit + ' size'

    def custom_label(self):
        # I assume this would return '5 cups'
        return '{} {}'.format(self.size, self.unit)

然后以你的形式:

class SkuForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        product = kwargs.pop('product', None)
        super(SkuForm, self).__init__(*args, **kwargs)

        self.fields['size'].label_from_instance = lambda obj: obj.custom_label()


    class Meta:
        model = Sku
        fields = ('size',)

答案 1 :(得分:0)

我检索了我想要的查询集:

def __init__(self, *args, **kwargs):
        self.product = kwargs.pop('product', None)
        super(SkuForm, self).__init__(*args, **kwargs)

        skus = self.product.sku_set.all()

        size_vals = []
        size_ids = []
        all_sizes = Size.objects.filter(sku__in=skus)

        for size in all_sizes:
            key = str(size.amount)+'_'+size.unit
            if any(key in d for d in size_vals):
                pass
            else:
                size_dict = {}
                size_dict[key]=size.id
                size_vals.append(size_dict)
        for size_val in size_vals:
            for d in size_val:
                id = size_val[d]
                size_ids.append(id)

self.fields['size'].queryset = Size.objects.filter(id__in=size_ids)