2

I'm trying to create a FormView that receives a string but it gives me a "objects already exists" error when I complete the field I give. What I'm trying to do is to create a view that checks if a certain "product" (model) exists, if that product really exists, redirect to another view based on the product "pk" to create another model.

Basically the course of action is like this:

  • Check if product exists.
  • if exists redirect to create order (model) view, else no nothing.
  • Fill the create order form, if valid, create the order and assign the product fk relation to order.

Here's my code

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

I'll be appreciated if you give me a tip for creating a correct get_success_url() for this case.

3
  • Can you paste the errors? Commented Jul 30, 2014 at 23:51
  • You are using super() override within form_valid for form_invalid. Why don't you just redirect based on if the object exists? Commented Jul 30, 2014 at 23:53
  • It returns me a "product with this codename already exists" error on forms. Commented Jul 31, 2014 at 3:45

1 Answer 1

1

Ok. I found a solution for my error. What caused the model already exists error was my ModelForm CheckProductForm. Codename attribute is unique, so my validation always returned False. What I did was to change my orginal ModelForm to a Form. This solved my whole issue. And for the form_invalid in form_valid issue. I've overwritten my form's clean_codename function to raise ValidationError if product doesn´t exist.

Here's the solution I found:

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: Sorry for the dumb questions.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.