0

我有一个 Item 对象,它与另一个对象 Option 具有多对多关系。我像这样从 Item 对象创建一个模型表单;

class Item(models.Model):
    category = models.ForeignKey(Category)
    name = models.CharField(max_length=200)
    price = models.DecimalField(max_digits=9, decimal_places=2, blank=True, null=True)
    options = models.ManyToManyField(Option)
class OptionForm(ModelForm):
    options = forms.ChoiceField(widget=forms.RadioSelect())
    class Meta:
        model = Item
        fields = ( 'options', )

当我在模板中呈现表单时,它呈现所有可用optionsItem对象(预期行为),即使那些不是由特定项目创建的。我希望能够加载options由用户选择的特定项目定义。我如何覆盖表单以实现这种行为。例如,如果没有表单,我可以通过其 id呈现Items自己的表单。Optionsitem = Item.objects.get(pk=id)

4

3 回答 3

0

尝试覆盖表单的 init 方法并将 Item pk 作为附加参数传入。这里的技巧是在调用父级 init 之前弹出参数。

class ItemOptionsForm(forms.ModelForm):
    class Meta:
        model = Item

    def __init__(self, *args, **kwargs):
        # pop 'item_id' as parent's init is not expecting it
        item_id = kwargs.pop('item_id', None)

        # now it's safe to call the parent init
        super(ItemOptionsForm, self).__init__(*args, **kwargs)

        # Limit options to only the item's options
        if item_id:
            try:
                item = Item.objects.get(id=item_id)
            except:
                raise ValidationError('No item found!')

            self.fields['options'] = forms.ChoiceField(item.options)

然后,在您看来,创建如下表单:

form = ItemOptionsForm(item_id=item_id)

这样做的好处是您可以提出 ValidationErrors 将显示在表单中。

请注意,这不会阻止某人向您的表单发布不属于该项目的选项 ID,因此您可能还需要覆盖 ModelForm.clean() 以验证选项。

于 2013-08-26T13:18:50.207 回答
0

动态定义 ModelForm 很难,因为它们与模型中的结构密切相关。不过,您可以使用一些巧妙的模板控制流程和视图渲染来获得您想要的效果。这是未经测试的,所以你用这个可能会有所不同。

<form method="post" action="">
    {{ formset.management_form }}
    {% for form in formset %}
        {{ form.id }}
        <ul>
     {% if user_option.category %}
            <li>{{ form.caregory }}</li>
     {% endif %}
     {% if user_option.name %}
            <li>{{ form.name }}</li>
     {% endif %}
     {% if user_option.p_opt %}
            <li>{{ form.price }}</li>
            <li>{{ form.options }}</li>
     {% endif %}
        </ul>
    {% endfor %}
</form> 

来自这里的 Djano 文档。

于 2013-08-26T12:57:16.550 回答
0

从链接django 学习:如何限制表单集中的字段选择?由@jingo 提供,我首先通过像这样创建动态表单来解决问题;

def partial_order_item_form(item):
    """dynamic form limiting optional_items to their items"""
    class PartialOrderItemform(forms.Form):
        quantity = forms.IntegerField(widget=forms.TextInput(attrs={'size':'2', 'class':'quantity','maxlength':'5'}))
        option = forms.ModelChoiceField(queryset=OptionalItems.objects.filter(item=item),widget= forms.RadioSelect())

    return PartialOrderItemform

然后像这样验证表格;

def show_item(request,id):
    option = get_object_or_404(Item,pk=id)
    if request.method == 'POST':
        form = partial_order_item_form(option)
        #bound form to POST data, 
        final_form = form(request.POST)
        # check validation of posted data
        if final_form.is_valid():
            order.add_to_order(request)
            url =urlresolvers.reverse('order_index',kwargs={'id':a.id})
            # redirect to order page
            return HttpResponseRedirect(url)
    else:
        form = partial_order_item_form(item=id)
    context={
        'form':form,
    }
    return render_to_response('item.html',context,context_instance=RequestContext(request))
于 2013-08-27T21:34:25.590 回答