Django formview使用modelform返回对象已存在的错误

时间:2014-07-30 23:09:49

标签: django django-forms django-views

我正在尝试创建一个接收字符串的FormView,但是当我完成我给出的字段时,它会给我一个“对象已存在”错误。我要做的是创建一个视图来检查某个“产品”(模型)是否存在,如果该产品确实存在,则根据产品“pk”重定向到另一个视图以创建另一个模型。

基本上,行动方针是这样的:

  • 检查产品是否存在。
  • 如果存在重定向以创建订单(模型)视图,则无其他任何内容。
  • 填写创建订单表单,如果有效,请创建订单并将产品fk关系分配给订单。

这是我的代码

views.py

class BuyOrderCheckProduct(generic.FormView):
    template_name = 'buy_order/buy_order_check_product.html'
    form_class = forms.CheckProductForm

    def form_valid(self, form):
        try:
            product = Product.objects.get(codename=form.cleaned_data['codename'])
        except Product.DoesNotExist:
            product = None
        if product:
            # Never enters here because correct existing codename gives form_invalid, don't know why
            return super(BuyOrderCheckProduct, self).form_valid()
        else:
            # It only enters when I input a non-existent codename for product
            return super(BuyOrderCheckProduct, self).form_invalid()

    def form_invalid(self, form):
        # I don't know why it enters here!
        return super(BuyOrderCheckProduct, self).form_invalid()  

    def get_success_url(self, **kwargs):
        # TODO: How to pass product pk as kwargs?
        return reverse_lazy('order_create', self.kwargs['pk'])

class BuyOrderCreate(generic.CreateView):
    template_name = 'buy_order/buy_order_create.html'
    form_class = forms.BuyOrderCreateForm
    success_url = reverse_lazy('buy_order_list')
    # TODO: Need to create a custom form_valid to add product fk to order.

forms.py

class CheckProductForm(forms.ModelForm):
    class Meta:
        model = Product
        fields = ['codename']

class BuyOrderCreateForm(forms.ModelForm):
    class Meta:
        model = BuyOrder

models.py

"""
ORDER
"""
class Order(models.Model):
    class Meta:
        verbose_name = u'orden'
        verbose_name_plural = u'ordenes'
        abstract = True

    unit_price = models.IntegerField(u"precio unitario", )
    quantity = models.IntegerField(u"cantidad", default=1)
    discount = models.IntegerField(u"descuento")

    def __unicode__(self):
        return self.code

class BuyOrder(Order):
    class Meta:
        verbose_name = u'orden de compra'
        verbose_name_plural = u'ordenes de compra'

    product = models.ForeignKey(Product, related_name="buy_orders", editable = False)
    bill = models.ForeignKey(BuyBill, related_name="orders", null=True, editable = False)

"""
PRODUCT
"""
class Product(models.Model):
    class Meta:
        verbose_name = u'producto'
        verbose_name_plural = u'productos'

    category        = models.ForeignKey(Category, verbose_name=u'categoría', related_name='products')
    codename        = models.CharField(u"código", max_length=100, unique=True)
    name            = models.CharField(u"nombre", max_length=100)
    description     = models.TextField(u"descripción", max_length=140, blank=True)
    sale_price      = models.IntegerField(u"precio de venta", default=0)
    purchase_price  = models.IntegerField(u"precio de compra", default=0)
    profit          = models.IntegerField(u"lucro", default=0)
    profit_margin   = models.IntegerField(u"margen de lucro", default=0)
    tax             = models.IntegerField(u"tasa", default=0)
    quantity        = models.IntegerField(u"cantidad", default=0)
    picture         = models.ImageField(u"imagen", upload_to='product_pictures', blank=True)
    group           = models.ForeignKey(Group, verbose_name=u'grupo', related_name='products')

    def __unicode__(self):
        return self.name

如果你给我一个提示,为这个案例创建一个正确的get_success_url(),我将不胜感激。

1 个答案:

答案 0 :(得分:1)

确定。我找到了一个解决我错误的方法。导致model already exists错误的原因是我的ModelForm CheckProductForm。 Codename属性是唯一的,因此我的验证总是返回False。我所做的是将我的原始ModelForm更改为Form。这解决了我的整个问题。对于form_valid问题中的form_invalid。如果产品不存在,我已经覆盖了我的表单的clean_codename函数来引发ValidationError。

以下是我找到的解决方案:

<强> views.py

class BuyOrderCheckProduct(generic.FormView):
    template_name = 'buy_order/buy_order_check_product.html'
    form_class = forms.CheckProductForm

    def form_valid(self, form):
        product = Product.objects.get(codename=form.cleaned_data['codename'])
        return redirect('buy_order_create', pk=product.pk)

<强> forms.py

class CheckProductForm(forms.Form):
    codename = forms.CharField(label=u'código')

    def clean_codename(self):
        try:
            product = Product.objects.get(codename=self.cleaned_data['codename'])
        except Product.DoesNotExist:
            raise forms.ValidationError("This codename doesn't exist.")
        return product
PD:抱歉愚蠢的问题。