I created a Form using one of my models i.e (Post), for my blog website. The form is meant for writers to post articles. In that form there is an Image attribute where the writer can upload an image. However, when i try to upload an image and post it, i get a feedback saying "field required", i think the form is not recognizing the image am trying to upload onto the the database. please help:
this is the form view from views.py:
def formview(request):
form = PostForm(request.POST or None)
if form.is_valid():
instance = form.save(commit=False)
instance.save()
return render(request, 'form.html', {'form':form})
this is from forms.py:
from django import forms
from .models import Post
class PostForm(forms.ModelForm):
image = forms.FileField
class Meta:
model = Post
fields = ['category', 'title', 'body', 'image', 'author']
this from my models.py:
class Post(models.Model):
category = models.ForeignKey(Category)
title = models.CharField(max_length=100)
pub_date = models.DateTimeField(auto_now_add=True)
body = models.TextField()
image = models.FileField()
author = models.ForeignKey(User, on_delete=models.CASCADE)
likes = models.IntegerField(default=1)
def __str__(self):
return self.title
this is my forms.html template:
<form method="POST" action="">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Post</button>
this is my urls.py:
from django.conf.urls import url
from . import views
app_name = 'posts'
urlpatterns = [
url(r'^$', views.homeview, name='homeview'),
url(r'^(?P<pk>[0-9]+)$', views.postview, name='postview'),
url(r'^category/(?P<pk>[a-zA-Z0-9]+)/$', views.categoryview,
name='categoryview'),
url(r'^author/(?P<pk>[a-zA-Z0-9]+)/$', views.authorview, name='authorview'),
url(r'^add_post/$', views.formview, name='formview'),
]
these are the pics might help explain what am trying to say:
Filling the form and selecting the picture
Error message after trying to post
Thank you
def formview(request):
if request.method == 'POST':
form = PostForm(request.POST,request.FILES)
if form.is_valid():
instance = form.save(commit=False)
instance.save()
else:
form = PostForm()
return render(request, 'form.html', {'form':form})
this form = PostForm(request.POST,request.FILES),you need add FILES to PostForm
Related
Basically I want to create a comment model section like youtube, Instagram, in which we can add comment/body in a detailed view of a post or video, and username which will be posted automatically from request.
models.py
class Comment(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')
name = models.ForeignKey(User, on_delete=models.CASCADE, related_name='comment_by')
email = models.EmailField()
body = models.TextField(help_text='Add a comment')
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
active = models.BooleanField(default=True)
class Meta:
ordering = ('created',)
def __str__(self):
return f'Comment by {self.name} on {self.post}'
forms.py
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ['email', 'body']
views.py
class PostDetailView(DetailView):
model = Post
# display comments and comment_form
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
qs = Comment.objects.filter(post=self.kwargs.get('pk'), active=True)
context['comments'] = qs.order_by('-created', '-updated')
context['comment_form'] = CommentForm() # adding empty form
return context
class CommentCreateView(LoginRequiredMixin, CreateView):
model = Comment
form_class = CommentForm
template_name = 'blog/post_detail.html'
success_url = reverse_lazy('post-detail')
new_comment = None
def form_valid(self, form):
post = self.get_object()
form.instance.post = post
form.instance.name = self.request.user
return super().form_valid(form)
I have post and comment models. I want to add a comment form in the post detail view. I'm able to add empty form but unable to post/add comments. When I submit the form with data in it, it shows this error: This page isn’t working. If the problem continues, contact the site owner. HTTP ERROR 405 PostDetailView works fine but doesn't know how to get working CommentCreateView in correct way. I've just started with class-based views. Thanks in advance.
You need to point the action="{% url 'create_comment %}" for the comment form to the correct view.
But replacing {% url 'create_comment %} with the URL path that points to the CommentCreateView view.
example: template.html
<form action="{% url 'create_comment %}" method="POST">
{% csrf_token %}
{{ comment_form }}
</form>
Have you solved your issue? I had the same problem and I solved by doing form.save() inside the form_valid method.
I have a view that renders a comment form along with a template:
views.py
def news(request):
if request.method == "POST":
form = CommentForm(request.POST)
if form.is_valid():
comment = form.save(commit=False)
comment.post = Article.objects.get(pk=2)
print(comment.post)
comment.author = request.user.username
comment.save()
return HttpResponseRedirect('')
else:
form = CommentForm()
return render(request, '../templates/news.html', context={"form": form})
models.py
class Comment(models.Model):
post = models.ForeignKey(Article, on_delete=models.CASCADE, related_name='comments', blank=True)
author = models.TextField()
text = models.TextField()
def __str__(self):
return self.text
forms.py
class CommentForm(ModelForm):
class Meta:
model = Comment
fields = ('text',)
In views.py, where comment.post is getting assigned to Article objects, I want the pk to be applied dynamically. I tried doing it in the templates, where putting {{ article.pk }} in the templates output the right pk for the Article object but I wasn't sure how I'd go about applying it to my form.
The templates look simple: Article object, below it a comment form.
The problem is simple, I want the news(request) function to dynamically apply the pk of the current Article object in order to make the comment go to the right post.
You can either use the path if it's unique or you can just add a hidden field and set the article pk as value:
<input name="post" type="hidden" value={{ article.pk }} />
And your form:
class CommentForm(ModelForm):
class Meta:
model = Comment
fields = ('text', 'post')
and you can access it from validated data in view.
I am learning Django. I have started with Django girls blog tutorial which is very basic. Now I want to convert this with the conceptual video blog where user can upload a video like Youtube and user will be able to play that video on the page blog. Besides, I want every post will be moderated by admin. Can anyone expert help me with some coding suggestion as I am newcomer? I have included the completed code bellow.
#ALL MODELS
from django.conf import settings
from django.db import models
from django.utils import timezone
class Post(models.Model):
author = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)
title = models.CharField(max_length=200)
text = models.TextField()
created_date = models.DateTimeField(default=timezone.now)
published_date = models.DateTimeField(blank=True, null=True)
def publish(self):
self.published_date = timezone.now()
self.save()
def __str__(self):
return self.title
###############################################################
# ALL VIEWS
from django.shortcuts import render, get_object_or_404, redirect
from .models import Post
from django.utils import timezone
from .forms import PostForm
def post_list(request):
posts = Post.objects.filter(
published_date__lte=timezone.now(
)).order_by('-published_date')
return render(request, 'blog/post_list.html', {'posts': posts})
def post_detail(request, pk):
post = get_object_or_404(Post, pk=pk)
return render(request, 'blog/post_detail.html', {'post': post})
def post_new(request):
if request.method == "POST":
form = PostForm(request.POST)
if form.is_valid():
post = form.save(commit=False)
post.author = request.user
# post.published_date = timezone.now()
post.save()
return redirect('post_detail', pk=post.pk)
else:
form = PostForm()
return render(request, 'blog/post_edit.html', {'form': form})
def post_edit(request, pk):
post = get_object_or_404(Post, pk=pk)
if request.method == "POST":
form = PostForm(request.POST, instance=post)
if form.is_valid():
post = form.save(commit=False)
post.author = request.user
# post.published_date = timezone.now()
post.save()
return redirect('post_detail', pk=post.pk)
else:
form = PostForm(instance=post)
return render(request, 'blog/post_edit.html', {'form': form})
###################################################################
# URL patterns
from django.urls import path
from . import views
urlpatterns = [
path('', views.post_list, name='post_list'),
path('post/<int:pk>/', views.post_detail, name='post_detail'),
path('post/new/', views.post_new, name='post_new'),
path('post/<int:pk>/edit/', views.post_edit, name='post_edit'),
]
#################################################################
# Forms
from django import forms
from .models import Post
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ('title', 'text',)
Guys I have solved my problem on my own. I have added just a simple code inside the video tag of html5. I have provided the code bellow.
Code for model:
from django.db import models
class VideoUploader(models.Model):
title = models.CharField(max_length = 100)
clip = models.FileField(upload_to='videos/%Y/%m/%d/')
description = models.TextField()
def __str__(self):
return self.title
HTML5 post list page:
{% block content %}
<div class="post">
<h2>{{ post.title }}</h2>
<video src="{{ post.clip.url }}" controls controlsList="nodownload"
width="640" height="480"></video>
<p>{{ post.description }}</p>
</div>
{% endblock %}
List item
Hello I am django beginner having tough time could someone please help me I don't know what am I doing wrong ?
I am trying to create a form and saving some data through it by using form.save(). And I am new to here also so don't mind any mistakes.
Here is my model:
from django.db import models
from stores.models import Store
class Category(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=30)
def __str__(self):
return self.name
class Product(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=30)
price = models.DecimalField(max_digits=5, decimal_places=5)
image = models.ImageField(upload_to='upload_to/')
category = models.ForeignKey(Category, default='Default', on_delete=models.CASCADE, blank=False, null=False)
store = models.ForeignKey(Store, on_delete=models.CASCADE, blank=False, null=False)
Here is my view:
from django.shortcuts import render, redirect
from .forms import NewPro
def pro(request):
if request.method == 'POST':
form = NewPro(request.POST)
if form.is_valid():
form.save()
return redirect('stores_list')
else:
form = NewPro()
return render(request, "default/add_product.html", {'form': form})
def product_list(request):
return render(request, 'default/product_list.html')
Here is my form:
from django import forms
from .models import Product
class NewPro(forms.ModelForm):
class Meta:
model = Product
fields = ('name', 'price', 'image','category', 'store',)
default/add_product.html :
{% extends 'default/base.html' %}
<html>
<head><title>E-Commerce App</title></head>
{% block content %}
<h1>Add Product details</h1>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Add Product</button>
</form>{% endblock %}
</html>
Settings.py settings
MEDIA_ROOT = '/home/saifi/Saif_project/final_project/MEDIA_ROOT/upload_to'
I can see some indentation issues in the view - but I'll guess that's just formatting when copying into Stackoverflow.
the form.is_valid() check will validate all your form fields and will only write to the database if all the input fields are valid. If it's not saving, the first place I'd check would be for form errors.
In your template you can render the errors with {{form.errors}} and it will list each field and error.
You forgot request.FILES in your pro view function, you have an image file after all.
def pro(request):
if request.method == 'POST':
form = NewPro(request.POST, request.FILES)
if form.is_valid():
form.save()
return redirect('stores_list')
else:
form = NewPro()
return render(request, "default/add_product.html", {'form': form})
Try using the form this way:
<form action="YOUR_URL_HERE" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Add Product</button>
</form>
I hope this will help. Welcome aboard ;)
Your indentation is wrong, the else should be for first 'if'
def pro(request):
form = NewPro()
if request.method == 'POST':
form = NewPro(request.POST)
if form.is_valid():
form.save()
return redirect('stores_list')
else:
form = NewPro()
return render(request, "default/add_product.html", {'form': form})
I can't seem to get a model form to load in my template.
models.py
from django.db import models
class Event(models.Model):
name = models.CharField(max_length=60)
start_datetime = models.DateTimeField()
end_datetime = models.DateTimeField()
description = models.TextField()
forms.py
from django import forms
from .models import Event
class EventForm(forms.ModelForm):
class Meta:
model = Event
fields = ['name']
views.py
from django.shortcuts import render
from .forms import EventForm
def index(request):
if request.method == 'POST':
form = EventForm(request.POST)
if form.is_valid():
form.save()
else:
form = EventForm()
return render(request, 'index.html')
index.html
<form method="POST" action="">
{% csrf_token %}
{{ form.as_p }}
</form>
<button type="submit">Save</button>
I can get the form to print to the console on load when adding print(form) in views.py on the GET request, but it doesn't load in the template.
Good examples on different ways to use forms : https://docs.djangoproject.com/en/1.11/topics/forms/#the-view
For index.html to render it is expecting form variable. So Render method call should be like this:
render(request, 'index.html', {'form': form})