Django表单选择字段来自关联ModelChoiceFields

0 投票
1 回答
1457 浏览
提问于 2025-04-16 09:00

我正在为一家商店制作一个表单,让客户可以从多个价格选项中选择。现在的Django模板看起来是这样的,而且运行得很好。

<select>
    <option>{{ p.equipment_list.season_price.currency }} {{ p.equipment_list.season_price.daily }} per day.</option>
    <option>{{ p.equipment_list.season_price.currency }} {{ p.equipment_list.season_price.weekly }} per week.</option>
    <option>{{ p.equipment_list.season_price.currency }} {{ p.equipment_list.season_price.monthly }} per month.</option>
</select>

我有一个产品'p',它属于一个叫做设备清单的组。这个清单的价格(season_price)会根据季节或促销活动而有所不同。这种设计让我们可以最大程度地定制和分开任务。以下是模型的定义:

class SeasonPrice(models.Model):
    name = models.CharField(_('Season Price'), max_length=300)
    slug = models.SlugField(max_length=150, unique=True)
    description = models.TextField(blank=True)

    currency = models.ForeignKey(Currency)
    daily = models.DecimalField(max_digits=10, decimal_places=2)
    weekly = models.DecimalField(max_digits=10, decimal_places=2)
    monthly = models.DecimalField(max_digits=10, decimal_places=2)
…

class EquipmentList(models.Model):
   ...
    name = models.CharField(_('Equipment List'), max_length=100)
    slug = models.SlugField(unique=True)
    description = models.TextField(blank=True)

    season_price = models.ForeignKey(SeasonPrice)
    ….

class Product(ImageModel):
     ...
    equipment_list = models.ForeignKey(EquipmentList, related_name='Equipment')

    name = models.CharField('Name', max_length=300)
    slug = models.SlugField(max_length=150, unique=True)
    description = models.TextField()
    is_active = models.BooleanField(default=True)
    quantity = models.IntegerField()

   …
    @models.permalink
    def get_absolute_url(self):
       return ('product_detail', (), {'product_slug': self.slug})

   ….

这个表单大概是这样的:

class ProductAddToCartForm(forms.Form):
    ...
    product_slug = forms.CharField(widget=forms.HiddenInput())
    price = forms.ModelChoiceField(EquipmentList)
    quantity = forms.IntegerField(widget=forms.TextInput(attrs={'size':'2', 'value':'1', 'class':'quantity'}), 
                                  error_messages={'invalid':'Please enter a valid quantity.'}, 
                                  min_value=1)
   ...

还有视图部分:

def show_product(request, product_slug, template_name="shop/product_detail.html"):

    p = get_object_or_404(Product, slug=product_slug)
    page_title = p.name


    # need to evaluate the HTTP method
    if request.method == 'POST':

        postdata = request.POST.copy()
        form = ProductAddToCartForm(request, postdata)

        if form.is_valid():
            cart.add_to_cart(request)
            url = urlresolvers.reverse('show_cart')
        return HttpResponseRedirect(url)
    else:

        form = ProductAddToCartForm(request=request, label_suffix=':')

    form.fields['product_slug'].widget.attrs['value'] = product_slug
    request.session.set_test_cookie()
    return render_to_response("shop/product_detail.html", locals(), context_instance=RequestContext(request))

我看到的所有ModelChoiceField的例子都是单层的外键(ForeignKey)。根据上面的内容,我希望能够将2到3个外键连接起来,输出一个数字字符串,这个字符串可以和顾客想要的数量相乘,然后放入购物车中。

谢谢

1 个回答

0

我觉得你提到的 ModelChoiceField 不太适合你展示的那个 <select> 选项。因为你是在选择一种货币和小数的组合,而不是选择一个模型实例。你可能想要创建一个临时的 ChoiceField

myform.fields['price'].choices = (
    ('1::3.50', "EUR 3.50 per day"),
    # ...
)

在这里,像 1::3.50 这样的字符串可以在清理或保存时用 split() 方法分开,得到货币的 ID 和金额的字符串。大概是这个意思。

撰写回答