I'm trying to create a posts form that lets the user create posts on my site. I've been stuck on how to pass request.user into the fields "author" and "participants". Could anybody help?
Here is my view:
def home(request):
if request.method == "POST":
form = PostForm(request.POST)
if form.is_valid():
form.save()
return redirect('')
My model:
class Post(models.Model):
author = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
body = models.TextField()
category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True)
participants = models.ManyToManyField(User, related_name="participants", blank=True)
created = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ["-created"]
def __str__(self):
return self.body
And my form:
from django.forms import ModelForm
from .models import Post
class PostForm(ModelForm):
class Meta:
model = Post
fields = '__all__'
For the author you can use this.
def home(request):
if request.method == "POST":
form = PostForm(request.POST)
form.author = request.user
if form.is_valid():
form.save()
return redirect('')
For the participants you can wait until the new Post is created an then add the User
if form.is_valid():
new_post = form.save()
new_post.participants.add(user)
I have an example with class based views where is easy to accomplish.
class PostCreateView(CreateView):
template_name = 'Post/article_create.html'
form_class = ArticleModelForm
queryset = Article.objects.all()
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['form_journal'] = JournalModelForm
return context
def dispatch(self, request, *args, **kwargs):
if request.method == 'POST':
want_redirect = request.POST.get('want_redirect')
if not want_redirect:
self.success_url = reverse_lazy('article:article-create')
return super(ArticleCreateView, self).dispatch(request, *args, **kwargs)
def form_valid(self, form):
form.instance.user = self.request.user //I think this is what you are trying to do
return super().form_valid(form)
Related
I tried to make a creation form for vacancy on my job search site, but i faced with problem. I have User model, company model and vacancy model. They are inherited by foreignkeys. And the problem is that user can use all companies for creation a vacancy instead of created by this user companies(User can create several companies). I tried to change creation form and view by filtering, but it didn't work out for me. I am new at django and i dint find anything to resolve my problem.
Model of company:
class Company(models.Model):
owner = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(('Title of Shop'), blank=True, max_length=255)
info = models.TextField(('Information about Shop'), null=True, blank=True)
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return str(self.title)
Model of vacancy:
class Vacancies(models.Model):
title = models.CharField(('Title of Vacancy'), blank=True, max_length=255)
city = models.ForeignKey(City, on_delete=models.CASCADE, default='363')
description = models.TextField(('Information about Vacancy'), null=True, blank=True)
employer = models.ForeignKey(Company, on_delete=models.CASCADE)
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ['-updated', '-created']
def __str__(self):
return str(self.title)
Create vacancy view:
#login_required(login_url='login')
def createVacancy(request):
form = VacanciesForm()
cities = City.objects.all()
if request.method == 'POST':
form = VacanciesForm(request.POST)
if form.is_valid():
form.save()
return redirect('home')
context = {'form': form, 'cities': cities}
return render(request, 'vacancy_form.html', context)
Vacancy form:
class VacanciesForm(ModelForm):
class Meta:
model = Vacancies
fields = '__all__'
What do I need to change to get the correct display of companies in the vacancy
Try this:
#login_required(login_url='login')
def create_vacancy(request):
user = request.user
cities = City.objects.all()
if request.method == 'POST':
form = VacanciesForm(data=request.POST, instance=user)
if form.is_valid():
form.save()
return redirect('home')
context = {'form': form, 'cities': cities}
return render(request, 'vacancy_form.html', context)
Also you can use in view:
def create_vacancy(request, logined_user_id):
vacancies = Vacancies.objects.filter(owner=logined_user_id)
...
And you can try some logic here:
class VacanciesForm(ModelForm):
vacancies = [some_logic]
class Meta:
model = Vacancies
fields = '__all__'
Finally, you can read docs:
modelforms
This work:
views
def createVacancy(request):
cities = City.objects.all()
form = VacanciesForm(data=request.POST, request=request)
if form.is_valid():
form.save()
return redirect('home')
context = {'form': form, 'cities': cities,}
return render(request, 'vacancy_form.html', context)
forms
class VacanciesForm(ModelForm, forms.Form):
def __init__(self, *args, **kwargs):
self.request = kwargs.pop("request")
super(VacanciesForm, self).__init__(*args, **kwargs)
self.fields['employer'].queryset = EmployerCard.objects.filter(owner=self.request.user)
class Meta:
model = Vacancies
fields = '__all__'
I am trying to let users create comment from listview on the social app am working on currently but am having a hard time working out the pattern. I keep getting the Error 404 when i try to load the listview. Here is Formlist view which my Post list view inherit from.
class FormListView(FormMixin, ListView):
def get(self, request, *args, **kwargs):
if request.method == 'GET':
post_id = request.GET.get('post_id')
comment = request.GET.get('comment', False)
post_obj = get_object_or_404(Post, pk=post_id)
session_obj = User.objects.get(username=request.user.username)
create_comment = Comment.objects.create(
post=post_obj,
user=session_obj,
comment=comment)
create_comment.save()
# From ProcessFormMixin
form_class = self.get_form_class()
self.form = self.get_form(form_class)
# From BaseListView
self.object_list = self.get_queryset()
allow_empty = self.get_allow_empty()
if not allow_empty and len(self.object_list) == 0:
raise Http404(_(u"Empty list and '%(class_name)s.allow_empty' is False.")
% {'class_name': self.__class__.__name__})
context = self.get_context_data(object_list=self.object_list, form=self.form)
return self.render_to_response(context)
def post(self, request, *args, **kwargs):
if request.method == "POST":
description = request.POST['description']
pic = request.FILES.get('pic', False)
#tag = request.FILES['tag']
user_obj = User.objects.get(username=request.user.username)
post_data = Post(username=user_obj,pic=pic,description=description,)
post_data.save()
messages.success(request, f'Posted Successfully')
return redirect('feed:feed')
return self.get(request, *args, **kwargs)
For one strange thing am able to create New Post from the PostListview but, Comment has been a challenge for me, for the past two weeks now and i have look on here but can't seem to find a solution that fits mine.
class PostListView(FormListView):
model = Post
form_class = NewPostForm
form_class = NewCommentForm
This is my comment model
class Comment(models.Model):
post = models.ForeignKey(Post, related_name='comments', on_delete=models.CASCADE)
username = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='comments', on_delete=models.CASCADE)
comment = models.CharField(max_length=500)
comment_date = models.DateTimeField(auto_now_add=True)
My Form.py
class NewCommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ['comment']
Here is my URL for PostListView.
path('', PostListView.as_view(), name='feed'),
I hope you are well.
I'm trying to create comment for user with one form field (content). I'd like to have the user field automatically filled in user value.
I. I started with this model but I got an error (1048, “Column 'user_id' cannot be null”):
models.py
class Comment(models.Model):
post = models.ForeignKey(Post,on_delete=models.CASCADE,related_name="comments")
user = models.ForeignKey(User,on_delete=models.CASCADE)
content = models.TextField(max_length=160)
publishing_date = models.DateField(auto_now_add=True)
def __str__(self):
return self.post.title
views.py
class PostDetail(generic.DetailView,FormMixin):
model = Post
context_object_name = 'post'
template_name = 'post_detail.html'
form_class = CreateCommentForm
def get_context_data(self, **kwargs):
context = super(PostDetail, self).get_context_data(**kwargs)
context['form'] = self.get_form()
return context
def form_valid(self, form):
if form.is_valid():
form.instance.post = self.object
form.save()
return super(PostDetail, self).form_valid(form)
else:
return super(PostDetail, self).form_invalid(form)
def post(self,*args,**kwargs):
self.object = self.get_object()
form = self.get_form()
if form.is_valid():
return self.form_valid(form)
else:
return self.form_valid(form)
def get_success_url(self):
return reverse('post_detail',kwargs={"slug":self.object.slug})
forms.py
class CreateCommentForm(forms.ModelForm):
def __init__(self,*args,**kwargs):
super(CreateCommentForm, self).__init__(*args,**kwargs)
self.helper = FormHelper()
self.helper.form_method="post"
self.helper.layout = Layout(
Field("content",css_class="form-control",style="margin-bottom:10px",rows="1"),
)
self.helper.add_input(Submit('submit','Comment',css_class="btn btn-sm",style="background-color: #0d6ec5;border-color: #0d6ec5;"))
class Meta:
model = Comment
fields = [
'content'
]
II. It worked from my admin panel but not from my website (I got this error: (1048, “Column 'user_id' cannot be null”)).
So I've decided to change my models with:
class Comment(models.Model):
post = models.ForeignKey(Post,on_delete=models.CASCADE,related_name="comments")
user = models.ForeignKey(User, blank=True, null=True, on_delete=models.CASCADE)
content = models.TextField(max_length=160)
publishing_date = models.DateField(auto_now_add=True)
def __str__(self):
return self.post.title
The thing is if a user post a comment, content is ok but there is no user related to the comment. Anyone has an idea?
You need to specify the .user attribute, probably to the logged in user:
from django.contrib.auth.mixins import LoginRequiredMixin
class PostDetail(LoginRequiredMixin, FormMixin, generic.DetailView):
model = Post
context_object_name = 'post'
template_name = 'post_detail.html'
form_class = CreateCommentForm
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['form'] = self.get_form()
return context
def form_valid(self, form):
form.instance.post = self.object
form.instance.user = self.request.user
return super().form_valid(form)
def post(self,*args,**kwargs):
self.object = self.get_object()
form = self.get_form()
if form.is_valid():
return self.form_valid(form)
else:
return self.form_valid(form)
def get_success_url(self):
return reverse('post_detail',kwargs={"slug":self.object.slug})
Note: You can limit views to a class-based view to authenticated users with the
LoginRequiredMixin mixin [Django-doc].
Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.
I was working on a comment section for post and was getting a django.db.utils.IntegrityError: NOT NULL constraint failed: new__score_comment.post_id
so I added null=True, blank=True to the post and user in the models.py class comment and proceeded with the comments addition section
but now when I am trying to link users and posts to the comment I am getting the same error
Here is the Models.py
class Comment(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE)
user = models.ForeignKey(User, on_delete=models.CASCADE)
# reply = models.ForeignKey('Comment', null=True, related_name="replies")
content = models.TextField(max_length=160)
timestamp = models.DateTimeField(auto_now_add=True)
def __str__(self):
return '{}-{}'.format(self.post.title, str(self.user.username))
Here is the views.py:
class PostDetailView(DetailView):
model = Post
template_name = "post_detail.html"
def get_context_data(self, *args, **kwargs):
context = super(PostDetailView, self).get_context_data()
post = get_object_or_404(Post, slug=self.kwargs['slug'])
comments = Comment.objects.filter(post=post).order_by('-id')
total_likes = post.total_likes()
liked = False
if post.likes.filter(id=self.request.user.id).exists():
liked = True
if self.request.method == 'POST':
comment_form = CommentForm(self.request.POST or None)
if comment_form.is_valid():
content = self.request.POST.get('content')
comment = Comment.objects.create(
post=post, user=request.user, content=content)
comment.save()
return HttpResponseRedirect("post_detail.html")
else:
comment_form = CommentForm()
context["total_likes"] = total_likes
context["liked"] = liked
context["comments"] = comments
context["comment_form"] = comment_form
return context
class PostCommentCreateView(LoginRequiredMixin, CreateView):
model = Comment
form_class = CommentForm
def form_valid(self, form):
post = get_object_or_404(Post, slug=self.kwargs['slug'])
form.instance.user = self.request.user
form.instance.post = post
return super().form_valid(form)
def form_invalid(self, form):
return HttpResponseRedirect(self.get_success_url())
def get_success_url(self):
return reverse('score:post-detail', kwargs=dict(slug=self.kwargs['slug']))
I have a Comment Form for my django project, which has a two columns: Author, Text.
I would like to make a author to be the currently looged user and be not able to edit that value. Is there a way to do it?
Here are my codes
forms.py
class CommentForm(forms.ModelForm):
author = forms.CharField(label = "名前", max_length=10,
widget=forms.TextInput(attrs={'style': 'position: relative;left: 0px;'}))
class Meta:
model = Comment
fields = ('author', 'text',)
views.py
def add_comment_to_post(request, pk):
post = get_object_or_404(Post, pk=pk)
if request.method == "POST":
form = CommentForm(request.POST)
if form.is_valid():
comment = form.save(commit=False)
comment.post = post
comment.save()
return redirect('Post-detail', pk=post.pk)
else:
form = CommentForm()
return render(request, 'blog/add_comment_to_post.html', {'form': form})
models.py
class Comment(models.Model):
post = models.ForeignKey('blog.Post', on_delete=models.CASCADE, related_name='comments')
author = models.CharField(max_length=200)
text = models.TextField()
created_date = models.DateTimeField(default=timezone.now)
approved_comment = models.BooleanField(default=False)
def approve(self):
self.approved_comment = True
self.save()
def __str__(self):
return self.text