NOT NULL constraint failed: blog_userpost.user_id - python

Im trying to create a way for people to post their ideas but is giving me this error:
NOT NULL constraint failed: blog_userpost.user_id. I want the user to have to be registered and login in order to make/read the posts.
views.py:
#create view
#login_required(login_url='login')
def userposts_create_view(request):
form= UserPostForm(request.POST or None)
if request.method == "POST":
if form.is_valid():
form = form.save()
form.save()
return HttpResponseRedirect("/Blog/posts/")
context= {'form': form,
}
return render(request, 'posts/userposts-create-view.html', context)
#list view
#login_required(login_url='login')
def userposts_list_view(request):
allposts= UserPost.objects.all()
context= {'allposts': allposts,
}
return render(request, 'posts/userposts-list-view.html', context)
#detail view
#login_required(login_url='login')
def userposts_detail_view(request, url=None):
post= get_object_or_404(UserPost, url=url)
context= {'post': post,
}
return render(request, 'posts/userposts-detail-view.html', context)
models.py
This are the categories I want the post to have, I can 'create' the post but whenever I submit it gives me the error.
User= settings.AUTH_USER_MODEL
class UserPost(models.Model):
user= models.ForeignKey(User, null=False,editable=False, verbose_name='Usuario', on_delete=models.CASCADE)
title= models.CharField(max_length=500)
content= models.TextField()
categories = models.ManyToManyField(Category, verbose_name='Categorias', blank=True,related_name="articles")
created_at = models.DateTimeField(auto_now_add=True, verbose_name='Creado el ')
updated_at = models.DateTimeField(auto_now=True, verbose_name='Actualizado el ')
def save(self, *args, **kwargs):
super(UserPost, self).save(*args, **kwargs)
forms.py
from django import forms
from .models import UserPost
class UserPostForm(forms.ModelForm):
class Meta:
model= UserPost
fields= ["title", "content","categories"]

One simple way is to use model's manager instead of form.save(). So in your condition (i.e. if form.is_valid()) you can use something like:
def userposts_create_view(request):
form= UserPostForm(request.POST or None)
if form.is_valid():
data = form.cleaned_data
categories = data.pop('categories', None)
user_post = UserPost.objects.create(**data, user=request.user)
if categories:
user_post.categories.add(*categories)
return HttpResponseRedirect("/Blog/posts/")
context= {'form': form}
return render(request, 'posts/userposts-create-view.html', context)

Related

Select a valid choice. That choice is not one of the available choices. error with Django Form

I've got a comment section html page and whenever I try to fill the fields and click sumbit it gives the following error - Select a valid choice. That choice is not one of the available choices.
views.py
#login_required(login_url='/accounts/login')
def add_comment(request, slug):
movie = Movie.objects.get(slug=slug)
form = CommentForm(request.POST)
if form.is_valid():
form.save()
return redirect('movie:movie_list')
context = {'form': form}
return render(request, 'add_comment.html', context)
forms.py
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ('commenter_name', 'comment_body')
widgets = {
'commenter_name': forms.TextInput(attrs={'class': 'form-control'}),
'comment_body': forms.Textarea(attrs={'class': 'form-control'}),
}
models.py
class Comment(models.Model):
movie = models.ForeignKey(Movie, related_name="comments", on_delete=models.CASCADE)
commenter_name = models.ForeignKey(User, default=None, on_delete=models.CASCADE)
comment_body = models.TextField()
date_added = models.DateTimeField(auto_now=True)
def __str__(self):
return '%s - %s' % (self.movie.title, self.commenter_name)
Please note I am able to add a comment through the /admin panel but once I tried adding an API to it things kinda went wrong.
I've deleted widgets from form.py which gave me the following error.
Afterwards I've encountered another error - NOT NULL constraint failed: movie_comment.post_id, after changing views.py I was able to post successfully
#login_required(login_url='/accounts/login/')
def comment_create(request, slug):
movie = Movie.objects.get(slug=slug)
if request.method == 'POST':
form = forms.CommentForm(request.POST, request.FILES)
if form.is_valid:
comment = form.save(commit=False)
comment.post = movie
comment.author = request.user
form.save()
return redirect('movies:movie_detail', slug=slug)
else:
form = forms.CommentForm()
return render(request, 'add_comment.html', {'form': form})
It now works.

NOT NULL constraint failed: blogs_comment.blog_id

I'm a beginner at django please help I've been trying to solve it for 2 hours, Thank you so much!
<I got this django error IntegrityError at /blog/431cdef3-d9e7-4abd-bf53-eaa7b188d0fd>
python
#Views
from django.shortcuts import render
from .models import Blog
from .forms import CommentForm
def home(request):
template = 'blogs/home.html'
blogs = Blog.objects.all()
context = {'blogs':blogs}
return render(request, template, context)
def blog(request, pk):
template = 'blogs/blog.html'
blog = Blog.objects.get(pk=pk)
context = {'blog':blog}
if request.method == 'POST':
form = CommentForm(request.POST)
form.save()
else:
form = CommentForm()
context['form'] = form
return render(request, template, context)
#Forms
from django.forms import ModelForm
from .models import Comment
class CommentForm(ModelForm):
class Meta:
model = Comment
fields = ['description']
#Models
from django.db import models
import uuid
class Blog(models.Model):
header = models.CharField(max_length=200)
posts = models.TextField(null=True)
footer = models.TextField(null=True, blank=True)
id = models.UUIDField(default=uuid.uuid4, unique=True, primary_key=True, editable=False)
def __str__(self):
return self.header
class Comment(models.Model):
blog = models.ForeignKey(Blog, on_delete=models.CASCADE, related_name='comments')
description = models.TextField(blank=True, null=True)
id = models.UUIDField(default=uuid.uuid4, unique=True, primary_key=True, editable=False)
def __str__(self):
return self.description `
Try with this:
def blog(request, pk):
template = 'blogs/blog.html'
blog = Blog.objects.get(pk=pk)
context = {'blog':blog}
if request.method == 'POST':
form = CommentForm(request.POST)
if form.is_valid():
comment = form.save(commit=False) # don't save the comment yet
comment.blog = blog # assign the blog
comment.save() # then save
else:
form = CommentForm()
context['form'] = form
return render(request, template, context)
Add the blog to the comment first before committing the comment to the database.
You didn't add with Foreignkey key value. Try this one.
def blog(request, pk):
template = 'blogs/blog.html'
blog = Blog.objects.get(pk=pk)
context = {'blog':blog}
if request.method == 'POST':
form = CommentForm(request.POST, instance=blog)
if form.is_valid():
form.save()
else:
form = CommentForm(instance=blog)
context['form'] = form
return render(request, template, context)

How to associate a username from the User model to another model in Django?

I currently have an index view with several input tags for a name, file and tags.
I'm trying to connect the model that handles that view (name: Uploaded) to the User model and associate the logged in users username to the Uploaded model.
Here's my view:
def index(request):
if request.method == 'POST':
form = FileUploadForm(request.POST, request.FILES)
if form.is_valid():
form.save()
else:
form = FileUploadForm
allTags = Tag.objects.all()
context = {'form': form, 'allTags': allTags}
return render(request, 'index.html', context)
and here's the Uploaded model:
class Uploaded(models.Model):
objects: models.Manager()
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="users")
name = models.CharField(max_length=50)
file = models.FileField(upload_to=MEDIA_ROOT)
tags = TaggableManager()
def __str__(self):
return f"{self.name} {self.file}"
You can "patch" the .instance wrapped in the form with the logged in user:
from django.contrib.auth.decorators import login_required
#login_required
def index(request):
if request.method == 'POST':
form = FileUploadForm(request.POST, request.FILES)
if form.is_valid():
form.instance.user = request.user
form.save()
else:
form = FileUploadForm()
allTags = Tag.objects.all()
context = {'form': form, 'allTags': allTags}
return render(request, 'index.html', context)
Note: You can limit views to a view to authenticated users with the
#login_required decorator [Django-doc].

Django, POST method, already logged in user

I write an app in django - sth like twitter, i have already log in/log out panel, and form when already logged in user can add a tweet.
A tweet has a 3 columns in database:
class Tweet(models.Model):
content = models.CharField(max_length=140)
creation_date = models.DateTimeField(auto_now_add=True)
user = models.ForeignKey(User, on_delete=models.CASCADE)
The form looks like:
class TweetForm(forms.Form):
content = forms.CharField(label='content')
And the view:
class TweetCreationView(LoginRequiredMixin, View):
permission_required = 'twitter.add_tweet'
raise_exception = True
permission_denied_message = 'You are not allowed being there!'
def get(self, request):
form = TweetForm()
return render(request, "twitter/add_tweet.html", {"form": form})
def post(self, request):
form = TweetForm(request.POST)
if form.is_valid():
if request.user.is_authenticated():
username = request.user.username
user_id = username.id
content = form.cleaned_data.get('content')
return render(request, "twitter/add_tweet.html", {"form": form})
How can i obtain an already logged in user in django and add his/her id to post view form?
do something similar to this. I did not check if this is working.
if request.user.is_authenticated():
if form.is_valid():
form = form.save(commit=False)
form.user = request.user
content = form.cleaned_data.get('content')
form.save()
return render(request, "twitter/add_tweet.html", {"form": form})
Ok,
I've managed to do it in kinda primitive way:
def post(self, request):
form = TweetForm(request.POST)
if form.is_valid():
t = Tweet()
current_user = request.user
t.content = form.cleaned_data.get('content')
t.user_id = current_user.id
t.save()
if t:
return redirect(reverse("base"), locals())
return render(request, "twitter/add_tweet.html", locals())

Django create a dropdown from a database model and save in another model

I am new to Django and Python and would like to attempt the following. Create a dropdown list from the data in a model and save the data in another model. However everytime I render the form, it is invalid and does not display the template, Any help would be greatly appreciated. Please help where I am going wrong.
Models.py:
class Part(models.Model):
category = models.TextField(default = ' ')
def __str__(self):
"""String for representing the Model object."""
return self.category
class UserItem(models.Model):
name= models.CharField(max_length = 50, null=True)
category = models.ForeignKey(Part, on_delete=models.SET_NULL, null=True)
def __str__(self):
"""String for representing the Model object."""
return self.category
Forms.py:
class DropDown(forms.ModelForm):
name = forms.CharField()
parts = forms.ModelChoiceField(queryset=Part.objects.values_list('category', flat=True).distinct())
class Meta:
model = UserItem
fields = ('name', 'category',)
Views.py:
def index(request):
query_results = Part.objects.all()
#part_list = DropDown()
if request.method == 'POST':
form = DropDown(request.POST)
if form.is_valid():
form.save()
return render(request,'index.html', {'query_results': query_results }, {'form': form } )
else:
print("invalid")
print (DropDown.errors)
form = DropDown()
return HttpResponseRedirect(reverse('genre_create') )
In your views.py, update the last return statement to below-
return render(request, "index.html",
{'form': form, 'query_results': query_results})
You can check here
You can infact get rid of the else block -
def index(request):
query_results = Part.objects.all()
if request.method == 'POST':
form = DropDown(request.POST)
if form.is_valid():
form.save()
return render(request,'index.html', {'query_results': query_results }, {'form': form } )
form = DropDown()
return render(request, "index.html",
{'form': form, 'query_results': query_results})
And, just because you have already created form in your python code, you don't need to write htmls for select and other tags. You can refer this link on form rendering options.

Categories