Django ModelForm does not save to database - django

I try to add a comment but it does not save it to the database. There is no error.
My Views is
def add_comment(request, id):
article = get_object_or_404(Article, id=id)
if request.method == "POST":
form = CommentForm(request.POST,instance=article)
if form.is_valid():
comment = form.save(commit=False)
comment.post = article
comment.save()
return redirect('articles:detail', pk=article.pk)
else:
form = CommentForm()
template="article/comment.html"
return render(request, template, {'form': form})
comment.html:
<form method="POST">{% csrf_token %}
{{form.as_p}}
<button type="submit">Send</button>
forms.py
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ('name', 'comment')

Related

Showing user's comments on posts in Django

I am adding a comment section for my posts in a blog, I reached to the part where I can add new comments and get it saved in the db and I can view them in the admin, but I am stuck to showing the username and the comment in the comment section, I have to go the admin and choose the name of the user and the blog name to appear in the page, how do i link them together
Here is the Models.py
class Comment(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE, null=True, blank=True)
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True)
content = models.TextField(max_length=160)
timestamp = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.content
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
fields = ['content', ]
success_url = reverse_lazy('score:post-detail')
def post(self, request, *args, **kwargs):
form = CommentForm(request.POST)
if form.is_valid():
post = form.save()
post.save()
print(args, kwargs, request.POST)
return redirect('score:post-detail', slug=kwargs['slug'])
here is the template
<form action={% url 'score:post-comment' post.slug %} method="post" class="comment-form" action=".">
{% comment %} <form method="post" class="comment-form" action="."> {% endcomment %}
{% csrf_token %}
{{ comment_form.as_p }}
{% if request.user.is_authenticated %}
<input type="submit" value="Submit" class="btn btn-outline-success">
{% else %}
<input type="submit" value="Submit" class="btn btn-outline-success" disabled> You must be Logged in to Comment
{% endif %}
</form>
here is the form
class CommentForm(forms.ModelForm):
content = forms.CharField(label="", widget=forms.Textarea(
attrs={'class': 'form-control', 'placeholder': 'Text goes here!!!', 'rows': '4', 'cols': '50'}))
class Meta:
model = Comment
fields = ('content',)
A CreateView is defined to remove most of the boilplate code, so you should not reimplement that in the post method, but let the CreateView do its work.
What you here should do is override the .form_valid(…) method [Django-doc] and the .form_invalid(…) method [Django-doc], and the .get_success_url(…) method [Django-doc] to redirect to the proper view:
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404
from django.urls import reverse
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']))

Django is rendering empty template to create new profile instead of submitting form

First some code:
models.py
class Findings(models.Model):
patient = models.ForeignKey(Profile, null=True, blank=True, on_delete=models.CASCADE)
finding_type = models.CharField(max_length=35, null=True)
upload = models.FileField(null=True, blank=True)
date_created = models.DateField(auto_now=True)
description = models.TextField(null=True, blank=True)
def __str__(self):
return self.finding_type
forms.py
class AddFindingForm(ModelForm):
class Meta:
model = Findings
fields = ('finding_type', 'description', 'upload', 'patient')
labels = {
'finding_type' : _('Rodzaj badania'),
'description': _('Opis'),
'upload': _('Dodaj plik'),
}
views.py
def add_finding(request):
form = AddFindingForm()
if request.method == 'POST':
form = UserProfileForm(request.POST, request.FILES)
if form.is_valid():
form = form.save(commit=False)
form.patient = request.user.profile
form.save()
return redirect('profile')
context = {'form': form}
return render(request, 'add_finding.html', context)
template
{% block content %}
<form method="POST" enctype="multipart/form-data" action="">
{% csrf_token %}
{{ form.as_p}}
<button type="submit"> Wyślij </button>
</form>
{% endblock %}
So, everytime i'm trying to submit a filled form it displays another form to create new Profile, even if i'm setting patient manually.
The empty form it's displaying is on the same url.
I have no idea why it's doing that...
You are submitting your request.POST data to wrong form. Doing this user's submitted data never gets into AddFindingForm() instead it should be,
def add_finding(request):
form = AddFindingForm()
if request.method == 'POST':
form = AddFindingForm(request.POST, request.FILES) # Change Here
if form.is_valid():
form = form.save(commit=False)
form.patient = request.user.profile
form.save()
return redirect('profile')
context = {'form': form}
return render(request, 'add_finding.html', context)

Upload multiple files with one single input

Multiple files do not save in admin, only the first saved in admin.
class Image(models.Model):
imageuploader_profile = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE, null=True, blank=True)
image = models.FileField(upload_to ='pictsagram/')
image_caption = models.CharField(max_length=700)
def upload(request):
form = PostForm(request.POST,request.FILES)
if request.method == "POST":
if form.is_valid():
for f in request.FILES.getlist('image'):
post = Image(image=f)
post = form.save(commit=False)
post.imageuploader_profile = request.user
print(request.user)
post.save()
form.save()
return redirect('/')
else:
form = PostForm()
return render(request, 'upload.html', {"form": form})
class PostForm(forms.ModelForm):
class Meta:
model = Image
fields = ('image_caption', 'image',)
<form action="{% url 'site:upload' %}" method="post" enctype="multipart/form-data">
{%csrf_token%}
<input type="file" name="file" multiple onchange="loadFile(event)" required="" id="id_file">
<button type="submit">Post</button>
</form>
It looks like your form is for an Image object, but you're trying to create multiple images from a single form submit.
You are creating the Image(), but it doesn't look like you're attaching it to the form. So you'll probably need to reorganize the view something like:
def upload(request):
if request.method == "POST":
for image_file in request.FILES.getlist('image'):
form = PostForm(request.POST, image_file)
if form.is_valid():
image = form.save(commit=False)
image.imageuploader_profile = request.user
image.save()
form.save()
return redirect('/')
else:
form = PostForm()
return render(request, 'upload.html', {"form": form})
Also, cut/paste can mess up formatting, but always double-check your indentation for intended flow.
use this code:-----------------------------
def upload(request):
form = PostForm(request.POST,request.FILES)
if request.method == "POST":
if form.is_valid():
for f in request.FILES.getlist('file'):
post = Image(image=f)
post = form.save(commit=False)
post.imageuploader_profile = request.user
print(request.user)
post.save()
form.save()
return redirect('/')
else:
form = PostForm()
return render(request, 'upload.html', {"form": form})
class PostForm(forms.ModelForm):
class Meta:
model = Image
fields = ('image_caption', 'image',)
<form action="{% url 'site:upload' %}" method="post" enctype="multipart/form-data">
{%csrf_token%}
<input type="file" name="file" multiple onchange="loadFile(event)" required="" id="id_file">
<button type="submit">Post</button>
</form>

Django: model doesn't create from models form

I try to create new object from model form, but objects isn't saved.
models.py
class VideoFile(models.Model):
name = models.CharField(max_length=200, blank=True)
file = models.FileField(upload_to="video/", validators=[validate_file_extension])
forms.py
class VideoCreateForm(ModelForm):
class Meta:
model = VideoFile
fields = ['name', 'file']
views.py
def add_video(request):
if request.method == "POST":
form = VideoCreateForm(request.POST, request.FILES)
if form.is_valid():
instance = form.save()
messages.success(request, "saved")
else:
messages.error(request, 'No success!.')
return redirect('vtv:video')
else:
form = VideoCreateForm()
return render(request, "vtv/video_add.html", {'form': form})
templates.html
<h3>Add new video</h3>
<form method = "post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" />
</form>
What's wrong?

django: if model has related models (ForeignKey) display Fields in main modelform

I have two models:
class Post(models.Model):
image = models.ImageField(upload_to='%Y/%m/%d')
title = models.CharField(max_length=200)
class Addimg(models.Model):
addimages = models.ForeignKey('Post', null=True)
addimg = models.ImageField(upload_to='images')
I wish to add images to my Post model with the "Addimg" model which works fine so far, but now i want that when I edit my parent model (Post), all the appended "Addimg" models also appear in the form. How could i do that? What would be the simplest solution?
Here is my view which handles my "parent" form:
def edit(request, pk):
post = get_object_or_404(Post, pk=pk)
if request.method == "POST":
form = PostForm(request.POST, request.FILES, instance=post)
if form.is_valid():
post = form.save(commit=False)
post.save()
return redirect('blog.views.detail', pk=post.pk)
else:
form = PostForm(instance=post)
return render(request, 'blog/edit.html', {'form': form})
and my forms.py:
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ('image', 'title',)
class AddimgForm(forms.ModelForm):
class Meta:
model = Addimg
fields = ('addimages', 'addimg',)
In my form template I have:
<form enctype="multipart/form-data" method="POST" class="post-form">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" >Save</button>
</form>
I would be very happy about any tips or usefull links since i'm very new to django/programming I even don't know the right keywords to search for. Thanks
Have a look at inline formsets.
Ok got it easy thing for django:
in forms.py:
from django.forms.models import inlineformset_factory
MyFormSet = inlineformset_factory(Post, Addimg, extra=1, fields = ('addimages', 'addimg',))
in views.py:
from .forms import PostForm, MyFormSet
def manageimages(request, pk):
post = get_object_or_404(Post, pk=pk)
if request.method == "POST":
formset = MyFormSet(request.POST, request.FILES, instance=post)
if formset.is_valid():
formset.save()
post.save()
return redirect('blog.views.someview')
else:
formset = MyFormSet(instance=post)
return render(request, 'blog/myformsettemplate.html', {'formset': formset})
and in myformsettemplate.html:
<form enctype="multipart/form-data" method="POST" class="post-form">
{% csrf_token %}
{{ formset.management_form }}
{% for form in formset %}
<div class="third">
{{ form.as_p }}
</div>
{% endfor %}
<button type="submit" >Save</button>
</form>