Rishik
Rishik

Reputation: 111

IntegrityError in Django even after defining form_valid

I'm trying to create and store the model form in the database. The model represents a product, and has field like the category, image, price... etc.

Here's the model

class Product(models.Model):
    categories = (("Books", "Books/Study Materials"),
                  ("Notebooks", "Notebooks/Rough Pads"),
                  ("Equipments", "Equipments/Tools"),
                  ("Cloths", "Cloths/Uniforms"),
                  ("Sports", "Sports/Sportswear"),
                  ("Miscellaneous", "Miscellaneous"))

    user = models.ForeignKey(User, on_delete = models.CASCADE)
    date_posted = models.DateTimeField(default = timezone.now)
    category = models.CharField(max_length = 13, choices = categories, default = "Miscellaneous")
    description = models.CharField(max_length = 75, null = True, blank = True)
    image = models.ImageField(default = "product/default.png", upload_to = "product")
    price = models.PositiveIntegerField()

    def __str__(self):
        return f"{self.category} by {self.user.username} for {self.price}"

    def save(self, *args, **kwargs):
        super().save()

        image = Image.open(self.image.path)
        image.thumbnail((600, 600), Image.ANTIALIAS)
        image = image.crop(((image.width - 600)//2, (image.height - 400)//2, (image.width + 600)//2, (image.height + 400)//2))
        image.save(self.image.path)

Here's the form that same model

class ProductAddForm(forms.ModelForm):
    description = forms.CharField(max_length = 75, widget = forms.TextInput(attrs = {'placeholder': 'Description'}), help_text = "Not more than 75 characters")
    image = forms.ImageField(required = False)
    price = forms.IntegerField(required = False, widget = forms.TextInput(attrs = {'placeholder': 'Price'}))

    class Meta:
        model = Product
        fields = ('category', 'description', 'image', 'price')

    def clean_description(self, *args, **kwargs):
        description = self.cleaned_data.get('description')
        if len(description) == 0:
            raise forms.ValidationError('Description is required!')
        if len(description) > 75:
            raise forms.ValidationError(f'Description should contains at most 75 characters, but bot {len(description)} characters!')
        return description

    def clean_price(self, *args, **kwargs):
        price = self.cleaned_data.get('price')
        if len(str(price)) == 0:
            raise forms.ValidationError('Product price is required!')
        elif price < 0:
            raise forms.ValidationError('Negative price..... seriously?')
        return price

And below is the view I'm creating using django's generic CreateView

class product_add(CreateView):
    model = Product
    form_class = ProductAddForm
    template_name = 'Product/product_add.html'

    def form_valid(self, form, *args, **kwargs):
        form.instance.author = self.request.user
        return super().form_valid(form)

Above I'm defining the form_valid method to set the user of the product as the current user. But when submitting the form, the error still says-

IntegrityError at /product/add/
NOT NULL constraint failed: Product_product.user_id

And even if I don't define the form_valid I'm still getting the same error!

The error is at super.save(), and it says Error in formatting: RelatedObjectDoesNotExist: Product has no user.

Upvotes: 0

Views: 181

Answers (1)

iklinac
iklinac

Reputation: 15738

Your Product relation to User is named user and not author

def form_valid(self, form):
    instance = form.save(commit=False)
    instance.user = self.request.user
    instance.save()

Upvotes: 1

Related Questions