我有以下三种关系:
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杯”?
答案 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)