mharre
mharre

Reputation: 263

Django: IntegrityError null value in column "user_id" of relation "" violates not-null constraint

I am trying to save data to the db but I am getting this error. I think I understand the error but am not sure how to correct it. Basically I am trying to post a review for a product and it seems like when trying to save to the DB it doesn't know which user is saving this review? I believe user_id is null for whatever reason. But honestly I could be wrong, I am kind of stuck at this point. I feel as if the easy solution is simply to set null = true in my user model but I do not want to do that. Any help is greatly appreciated

models:

class Review(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    product = models.ForeignKey(Product, on_delete=models.SET_NULL, null=True)
    rating = models.DecimalField(max_digits=2, decimal_places=1, validators=[MinValueValidator(Decimal('0.1'))])
    comment = models.TextField(validators=[MinLengthValidator(10)])
    date = models.DateField(auto_now=True)

    def __str__(self):
        return str(self.user) 

class Product(models.Model):
    name = models.CharField(max_length=120)
    shortened_name = models.CharField(max_length=50)
    date_of_creation = models.CharField(max_length=20, null=True)
    history = models.CharField(max_length=255)
    price = models.DecimalField(max_digits=9, decimal_places=2)
    discount_price = models.FloatField(blank=True, null=True)
    style = models.CharField(max_length=50)
    artist = models.ForeignKey(Artist, on_delete=models.SET_NULL, null=True)
    image = models.ImageField(upload_to='images', null=True)
    slug = models.SlugField()
    
    

    def __str__(self):
        return self.name
    
    def get_absolute_url(self):
        return reverse('product', args=[self.slug])

    def save(self, *args, **kwargs):
        self.slug = slugify(self.shortened_name)
        super().save(*args, **kwargs)

    def get_add_to_cart_url(self):
        return reverse('add_to_cart', kwargs={
            'slug': self.slug
        })

    def get_remove_from_cart_url(self):
        return reverse('remove_from_cart', kwargs={
            'slug': self.slug
        })

form:

class ReviewForm(forms.ModelForm):
    class Meta:
        model = Review
        exclude = ['user', 'date']
        widgets = {
            'product': forms.Select(attrs={
                'class': 'form-control'
            }),
            'rating': forms.NumberInput(attrs={
                'class': 'form-control',
                'placeholder': '5.0..'
            }),
            'comment': forms.Textarea(attrs={
                'class': 'form-control'
            })
        }

view:

class MyOrdersView(LoginRequiredMixin, View):
    def get(self, request, *args, **kwargs):
        try:
            order = ShoppingCartOrder.objects.filter(user=self.request.user, ordered=True)
            form = ReviewForm()
            context = {
                'object': order,
                'form': form
            }
            return render(request, 'my_site/my_orders.html', context)
        except ObjectDoesNotExist:
            messages.warning(request, 'You do not have any orders')
            return redirect('all_products')

    def post (self, request, *args, **kwargs):
        form = ReviewForm(request.POST)
        if form.is_valid():
            test = form.save()

            return redirect('starting_page')
        return redirect('my_orders')

Upvotes: 1

Views: 726

Answers (1)

binpy
binpy

Reputation: 4194

You are using ReviewForm with excluding the user field, so I think you just forgot to save the user field. try to change:

test = form.save()

into:

test = form.save(commit=False)
test.user = request.user
test.save()

Upvotes: 2

Related Questions