Issue: NOT NULL constraint failed
Question:
So I’m currently building an online webshop for my school project. In the webshop, the user should be able to submit a review on each product. Tho I’m having issues when trying to submit the review. It gives me this error:
NOT NULL constraint failed:
Ive been stuck on this for about 15 hours I cant seem to solve it. I would appreciate all the help I can get.
Traceback:
Traceback (most recent call last):
File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/backends/sqlite3/base.py", line 423, in execute
return Database.Cursor.execute(self, query, params)
The above exception (NOT NULL constraint failed: products_reviewrating.user_id) was the direct cause of the following exception:
File "/workspace/.pip-modules/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/workspace/.pip-modules/lib/python3.8/site-packages/django/core/handlers/base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/workspace/webster00/products/views.py", line 91, in submit_review
newreview.save()
File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/models/base.py", line 726, in save
self.save_base(using=using, force_insert=force_insert,
File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/models/base.py", line 763, in save_base
updated = self._save_table(
File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/models/base.py", line 868, in _save_table
results = self._do_insert(cls._base_manager, using, fields, returning_fields, raw)
File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/models/base.py", line 906, in _do_insert
return manager._insert(
File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/models/query.py", line 1270, in _insert
return query.get_compiler(using=using).execute_sql(returning_fields)
File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1410, in execute_sql
cursor.execute(sql, params)
File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/backends/utils.py", line 98, in execute
return super().execute(sql, params)
File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/backends/utils.py", line 66, in execute
return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/backends/utils.py", line 75, in _execute_with_wrappers
return executor(sql, params, many, context)
File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/utils.py", line 90, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/backends/sqlite3/base.py", line 423, in execute
return Database.Cursor.execute(self, query, params)
Exception Type: IntegrityError at /products/submit_review/6/
Exception Value: NOT NULL constraint failed: products_reviewrating.user_id
Views.py
def submit_review(request, product_id):
print(f'product_id: {product_id}')
url = request.META.get('HTTP_REFERER')
if request.method == 'POST':
try:
product = Product.objects.get(id=product_id)
reviews = ReviewRating.objects.filter(user=request.user.userprofile, product=product).first()
form = ReviewForm(request.POST, instance=reviews)
newreview = form.save(commit=False)
newreview.product = product
newreview.save()
form.save()
messages.success(request, 'Thank you! Your review has been updated')
return redirect(url)
except ReviewRating.DoesNotExist:
form = ReviewForm(request.POST)
if form.is_valid():
data = ReviewRating()
data.subject = form.cleaned_data['subject']
data.rating = form.cleaned_data['rating']
data.review = form.cleaned_data['review']
data.ip = request.META.get('REMOTE_ADDR')
data.product_id = product_id
data.user_id = request.user.id
data.save()
messages.success(request, 'Thank you! Your review has been submited.')
return redirect(url)
The Review is also not showing in the django admin.
Answers:
You’re not assigning all of the fields (user
in this case) in the newreview
case.
Add
newreview.user = request.user
before the save
– and you may need to repeat this for other fields you haven’t dealt with.
You can probably simplify the view a lot with:
from django.contrib.auth.decorators import login_required
from django.shortcuts import get_object_or_404
@login_required
def submit_review(request, product_id):
product = get_object_or_404(Product, pk=product_id)
userprofile = request.user.userprofile
review = ReviewRating.objects.filter(
user=userprofile, product=product
).first()
if request.method == 'POST':
action = ('submitted', 'updated')[review is not None]
form = ReviewForm(request.POST, request.FILES, instance=review)
if form.is_valid():
form.instance.product_id = product_id
form.instance.user = userprofile
form.instance.ip = request.META.get('REMOTE_ADDR')
form.save()
messages.success(
request, f'Thank you! Your review has been {action}.'
)
return redirect(URL)
else:
form = ReviewForm(request.POST, request.FILES, instance=review)
return render(request, 'name-of-some-template.html', {'form': form})
Note: You can limit views to a view to authenticated users with the
@login_required
decorator [Django-doc].
Note: It is often better to use get_object_or_404(…)
[Django-doc],
then to use .get(…)
[Django-doc] directly. In case the object does not exists,
for example because the user altered the URL themselves, the get_object_or_404(…)
will result in returning a HTTP 404 Not Found response, whereas using
.get(…)
will result in a HTTP 500 Server Error.
So I’m currently building an online webshop for my school project. In the webshop, the user should be able to submit a review on each product. Tho I’m having issues when trying to submit the review. It gives me this error:
NOT NULL constraint failed:
Ive been stuck on this for about 15 hours I cant seem to solve it. I would appreciate all the help I can get.
Traceback:
Traceback (most recent call last):
File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/backends/sqlite3/base.py", line 423, in execute
return Database.Cursor.execute(self, query, params)
The above exception (NOT NULL constraint failed: products_reviewrating.user_id) was the direct cause of the following exception:
File "/workspace/.pip-modules/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/workspace/.pip-modules/lib/python3.8/site-packages/django/core/handlers/base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/workspace/webster00/products/views.py", line 91, in submit_review
newreview.save()
File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/models/base.py", line 726, in save
self.save_base(using=using, force_insert=force_insert,
File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/models/base.py", line 763, in save_base
updated = self._save_table(
File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/models/base.py", line 868, in _save_table
results = self._do_insert(cls._base_manager, using, fields, returning_fields, raw)
File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/models/base.py", line 906, in _do_insert
return manager._insert(
File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/models/query.py", line 1270, in _insert
return query.get_compiler(using=using).execute_sql(returning_fields)
File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1410, in execute_sql
cursor.execute(sql, params)
File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/backends/utils.py", line 98, in execute
return super().execute(sql, params)
File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/backends/utils.py", line 66, in execute
return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/backends/utils.py", line 75, in _execute_with_wrappers
return executor(sql, params, many, context)
File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/utils.py", line 90, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/backends/sqlite3/base.py", line 423, in execute
return Database.Cursor.execute(self, query, params)
Exception Type: IntegrityError at /products/submit_review/6/
Exception Value: NOT NULL constraint failed: products_reviewrating.user_id
Views.py
def submit_review(request, product_id):
print(f'product_id: {product_id}')
url = request.META.get('HTTP_REFERER')
if request.method == 'POST':
try:
product = Product.objects.get(id=product_id)
reviews = ReviewRating.objects.filter(user=request.user.userprofile, product=product).first()
form = ReviewForm(request.POST, instance=reviews)
newreview = form.save(commit=False)
newreview.product = product
newreview.save()
form.save()
messages.success(request, 'Thank you! Your review has been updated')
return redirect(url)
except ReviewRating.DoesNotExist:
form = ReviewForm(request.POST)
if form.is_valid():
data = ReviewRating()
data.subject = form.cleaned_data['subject']
data.rating = form.cleaned_data['rating']
data.review = form.cleaned_data['review']
data.ip = request.META.get('REMOTE_ADDR')
data.product_id = product_id
data.user_id = request.user.id
data.save()
messages.success(request, 'Thank you! Your review has been submited.')
return redirect(url)
The Review is also not showing in the django admin.
You’re not assigning all of the fields (user
in this case) in the newreview
case.
Add
newreview.user = request.user
before the save
– and you may need to repeat this for other fields you haven’t dealt with.
You can probably simplify the view a lot with:
from django.contrib.auth.decorators import login_required
from django.shortcuts import get_object_or_404
@login_required
def submit_review(request, product_id):
product = get_object_or_404(Product, pk=product_id)
userprofile = request.user.userprofile
review = ReviewRating.objects.filter(
user=userprofile, product=product
).first()
if request.method == 'POST':
action = ('submitted', 'updated')[review is not None]
form = ReviewForm(request.POST, request.FILES, instance=review)
if form.is_valid():
form.instance.product_id = product_id
form.instance.user = userprofile
form.instance.ip = request.META.get('REMOTE_ADDR')
form.save()
messages.success(
request, f'Thank you! Your review has been {action}.'
)
return redirect(URL)
else:
form = ReviewForm(request.POST, request.FILES, instance=review)
return render(request, 'name-of-some-template.html', {'form': form})
Note: You can limit views to a view to authenticated users with the
@login_required
decorator [Django-doc].
Note: It is often better to use
get_object_or_404(…)
[Django-doc],
then to use.get(…)
[Django-doc] directly. In case the object does not exists,
for example because the user altered the URL themselves, theget_object_or_404(…)
will result in returning a HTTP 404 Not Found response, whereas using
.get(…)
will result in a HTTP 500 Server Error.