问题
Django : Why is my submit interest form not submitted because of an integrity error issue? Did I write my view or template wrongly? How should I solve this error as i've never encountered before. i searched on this website and saw some profile examples but mine is blog post and i dont really understand how their change could solve the error..
should it be 'obj.interestsender=user' and not 'object. interestreceiver=user' and whether i also need 'obj.interestreceiver=blog_post.author' in the view? Thank you!!!
I received the following integrity error:
IntegrityError at /HomeFeed/submitinterest/slug-5 null value in column "interestreceiver_id" of relation "HomeFeed_interest" violates not-null constraint DETAIL: Failing row contains (17, 2021-01-06 10:54:25.489884+00, t, ddfe, efeffe, 5, documents/Discussion_between_joowon_and_SLDem_-_2021-01-05.pdf, 13, null, null, 1).
Apart from the integrity error, I also face the following issue: why is it that after I submit the request to that particular post, I am unable to submit interest to other posts that belong to the same user. Because my intent is that you cannot submit interest again to the same post and not the same user.
views.py
@login_required
def submit_interest_view(request, slug):
user = request.user
blog_post = get_object_or_404(BlogPost, slug=slug)
num_blogpost = BlogPost.objects.filter(author=user).count()
if blog_post.author.email == user.email:
return HttpResponse('You cannot submit interest to your own post.')
interest_requests = Interest.objects.filter(interestsender=user, interestreceiver=blog_post.author, is_active=True)
if interest_requests.exists():
return HttpResponse('You have already submitted your interest to this post.')
if request.method == 'POST': # use request.method == 'POST' to submit POST request (like submitting a form)
form = SubmitInterestForm(request.POST, request.FILES)
if form.is_valid():
obj = form.save(commit=False)
author = Account.objects.get(email=user.email) # use 'author = user.account' if there is OneToOne relation between user and account
obj.author = author
obj.blog_post = blog_post
obj.save()
messages.success(request, 'Your interests have been submitted', extra_tags='submittedinterest')
context['success_message'] = "Updated"
if request.META.get('HTTP_REFERER') == request.build_absolute_uri(reverse("HomeFeed:main")):
return redirect(reverse("HomeFeed:main"))
elif request.META.get('HTTP_REFERER') == request.build_absolute_uri(reverse("HomeFeed:detail", kwargs={'slug': slug })):
return redirect(reverse('HomeFeed:detail', kwargs={'slug': slug}))
else:
return redirect(reverse('HomeFeed:main'))
#return redirect(reverse('HomeFeed:detail', kwargs={'slug': slug})) # redirect to your post detail but use reverse to pass kwargs not just redirect
else:
messages.warning(request, 'Something went wrong. Please try again..', extra_tags='wronginterest')
return render(request, "HomeFeed/submitinterest.html", {'form': form,'user': user, 'num_blogpost': num_blogpost, 'blog_post': blog_post})
else:
form = SubmitInterestForm() # if request.method isnt POST you still need to define your form so it can be displayed
return render(request, "HomeFeed/submitinterest.html", {'form': form,'user': user, 'num_blogpost': num_blogpost, 'blog_post': blog_post}) # context dict
forms.py
HomeFeed: forms.py:
class SubmitInterestForm(forms.ModelForm):
class Meta:
model= Interest
fields = ['my_name', 'my_thoughts','short_file',]
models.py
class Interest(models.Model):
interestsender = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='interestsender', on_delete=models.CASCADE)
interestreceiver = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='interestreceiver', on_delete=models.CASCADE)
timestamp = models.DateTimeField(auto_now_add=True)
is_active = models.BooleanField(blank=False, null=False, default=True)
my_name = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
blog_post = models.ForeignKey(BlogPost, on_delete=models.CASCADE)
my_thoughts = models.TextField(max_length=5000, null=False, blank=False)
short_file = models.FileField(upload_to='documents/', null=True, blank=True)
def upload_location(instance, filename):
#you define this variable called file_path. It belongs to the HomeFeed app, and takes in the parameter of author id, title of blog post with the file name that the author uploads it, and you want to format it
file_path = 'HomeFeed/{author_id}/{title}-{filename}'.format(
author_id=str(instance.author.id),title=str(instance.chief_title), filename=filename)
#the above will let you insert the strings, you want to take ID of the user who is uploading and converting it into a string, and also the title and file name, converting them into string
# return file path means where the images is stored, either the local machine/ production environment which will be the name file stored in the content delivery network
return file_path
class BlogPost(models.Model):
chief_title = models.CharField(max_length=50, null=False, blank=False)
body = models.TextField(max_length=5000, null=False, blank=False)
likes = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='blog_posts', blank=True)
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
slug = models.SlugField(blank=True, unique=True)
date_published = models.DateTimeField(auto_now_add=True, verbose_name="date published")
class Account(AbstractBaseUser):
email = models.EmailField(verbose_name="email", max_length=60, unique=True)
username = models.CharField(max_length=30, unique=True)
date_joined = models.DateTimeField(verbose_name='date joined', auto_now_add=True)
last_login = models.DateTimeField(verbose_name='last login', auto_now=True)
is_admin = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
html:
submit_interest.thml
<form method="post" enctype="multipart/form-data">{% csrf_token %}
<div class="form-group">
<input class="form-control bg-white form-control-plaintext c" rows="10" type="text" name="my_name" id="my_name" placeholder="Name: {{ request.user.username }}" readonly></input>
</div>
<div class="form-group">
<label for="my_thoughts text-dark">thoughts:</label>
<textarea class="form-control" rows="6" type="text" name="my_thoughts" id="my_thoughts" placeholder="My thoughts..." required></textarea >
</div>
<label for="short_file " class="text-dark">Brief file (Optional):</label>
<input type="file" class="btn btn-md btn-light" name="short_file" id="short_file"> <!--<button type="submit" class="btn btn-md btn-info">Upload</button>-->
{% if uploaded_file_url %}
<p>File uploaded at: <a href="{{ uploaded_file_url }}">{{ uploaded_file_url }}</a></p>
{% endif %}
<button class="submit-button btn btn-lg btn-primary mt-3 btn-block col-lg-6 offset-lg-3 " type="submit">Submit Interest</button>
</form>
urls.py
app_name = 'HomeFeed'
urlpatterns = [
path('', home_feed_view , name= "main"),
path('submitinterest/<slug>', submit_interest_view, name= "submitinterest"),
`
Traceback:
'''
Traceback (most recent call last):
File "lib/python3.8/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "lib/python3.8/site-packages/django/core/handlers/base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "lib/python3.8/site-packages/django/core/handlers/base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "lib/python3.8/site-packages/django/contrib/auth/decorators.py", line 21, in _wrapped_view
return view_func(request, *args, **kwargs)
File "HomeFeed/views.py", line 262, in submit_interest_view
obj.save()
File "lib/python3.8/site-packages/django/db/models/base.py", line 740, in save
self.save_base(using=using, force_insert=force_insert,
File "lib/python3.8/site-packages/django/db/models/base.py", line 777, in save_base
updated = self._save_table(
File "lib/python3.8/site-packages/django/db/models/base.py", line 870, in _save_table
result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
File "lib/python3.8/site-packages/django/db/models/base.py", line 907, in _do_insert
return manager._insert([self], fields=fields, return_id=update_pk,
File "/lib/python3.8/site-packages/django/db/models/manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "lib/python3.8/site-packages/django/db/models/query.py", line 1186, in _insert
return query.get_compiler(using=using).execute_sql(return_id)
File "/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1375, in execute_sql
cursor.execute(sql, params)
File "lib/python3.8/site-packages/django/db/backends/utils.py", line 99, in execute
return super().execute(sql, params)
File "lib/python3.8/site-packages/django/db/backends/utils.py", line 67, in execute
return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
File "lib/python3.8/site-packages/django/db/backends/utils.py", line 76, in _execute_with_wrappers
return executor(sql, params, many, context)
File "lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "lib/python3.8/site-packages/django/db/utils.py", line 89, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
django.db.utils.IntegrityError: null value in column "interestreceiver_id" of relation "HomeFeed_interest" violates not-null constraint
DETAIL: Failing row contains (17, 2021-01-06 10:54:25.489884+00, t, ddfe, efeffe, 5, documents/Discussion_between_joowon_and_SLDem_-_2021-01-05.pdf, 13, null, null, 1).
'''
回答1:
This error is saying : in you database there is a null value stored whole the column have not null constraint
Quick fix: Add to the field causing the error. blank=True, null=True
When null is not an option in interestreceiver then you will have to manually remove the null values from the database!
You can do that by running this command
Python manage.py dbshell
EDIT:
Please check that you do not have null values in the database. Null values can be generated automatically if you created new fields. If you adding the field recently then you will have to pass Null= True, no other way. Then you make the blog post view only for authenticated users.
When this error come up when you submit the blog then, you are somehow passing a null value for the intrestreceiver here:
# add this line before intrest_request to make sure you are not passing Null value
print(blog_post.author, user)
interest_requests = Interest.objects.filter(interestsender=user,
interestreceiver=blog_post.author, is_active=True)
and see if the value is coming throw.
when the value is coming through and you are still getting the error then I do not know how did you structure your database, review related_field documentation on here: https://docs.djangoproject.com/en/3.1/topics/db/queries/#backwards-related-objects
来源:https://stackoverflow.com/questions/65594553/django-integrityerror-null-value-in-column-interestreceiver-id-of-relation-h