Cannot see the form input field at all - python

I would like to collect the content that user input, then change the database using POST method. But i just blank when i clicked post button on the website.
Here's the views.py
class PostTweet(View):
def post(self, request, username):
form = TweetForm(request.POST)
print form.is_valid()
print request.POST
print form.errors
if form.is_valid():
user = User.objects.get(username=username)
tweet = Tweet(text=form.cleaned_data['text'],
user=user,
country=form.cleaned_data['country'])
tweet.save()
return HttpResponseRedirect('/user/'+username)
else:
form = TweetForm()
return render(request, 'profile.html', {'form':form})
class Profile(View):
"""
User Profile page reachable from /user/<username> URL
"""
def get(self, request, username):
params = {}
user = User.objects.get(username = username)
tweets = Tweet.objects.filter(user=user)
params["tweets"] = tweets
params["user"] = user
return render(request, 'profile.html', params)
forms.py
from django import forms
class TweetForm(forms.Form):
text = forms.CharField(widget=forms.Textarea, max_length=160)
country = forms.CharField(widget=forms.HiddenInput(),required=False)
profile.html
{% extends "base.html" %}
{% block content %}
<div class="row clearfix">
<div class="col-md-6 col-md-offset-3 column">
<form id="form" method="POST" action="post/">{% csrf_token %}
<div class="col-md-8 fieldWrapper">
{{ form }}
<span class="input-group-btn">
<button class="btn btn-default" type="submit">Post</button>
</span>
</div>
</form>
</div>
<h3> </h3>
<div class="col-md-12 column">
{% for tweet in tweets %}
<div class="well">
<span>{{ tweet.text}}</span>
</div>
{% endfor %}
</div>
</div>
{% endblock %}
Here's the urls.py
from django.conf.urls import include, url, patterns
from django.contrib import admin
from tweets.views import Index, Profile, PostTweet, HashTagCloud
admin.autodiscover()
urlpatterns = patterns('',
url(r'^$', Index.as_view()),
url(r'^user/(\w+)/$', Profile.as_view()),
url(r'^admin/', include(admin.site.urls)),
url(r'^user/(\w+)/post/$', PostTweet.as_view()),
url(r'^hashTag/(\w+)/$', HashTagCloud.as_view()),
)
Anyone just give me a hint would be appreciated :-)

Adding {{form}} only should not render the field. form is an object with fields as properties. In your html try substituting {{form}} with {{form.text}}
Also you can try passing the object "form" as follows:
return render(request, 'profile.html', form = form)

Related

Model form is not able to save in database

I am a beginner in Django
I want to save a form data in database but i am not able to save, followed some tutorials also.
form.py:
from django.forms import ModelForm
from .models import *
class listsForm(ModelForm):
class Meta:
model = todo
fields = "__all__"
views.py:
from django.shortcuts import render
from .models import *
from .form import *
def index(request):
lists = todo.objects.all()
form = listsForm()
context = {
'lists':lists,
'form':form,
}
if request.method == 'POST':
form = listsForm(request.POST)
if form.is_valid:
form.save()
return render(request, 'index.html', context)
models.py:
from django.db import models
class todo(models.Model):
title = models.CharField(max_length=200)
description = models.TextField(null=True, blank=True)
created = models.DateField(auto_now_add=True)
def __str__(self):
return self.title
Why are you rendering listsForm?
Your form should be in the template not rendered!
In index.html, your form should looks like the following:
<form action="{% url 'create_todo' %}" method="POST">
{% csrf_token %}
<div class="form-group">
<label for="title">Title</label>
<input type="text" name="title" class="form-control" id="title" required></div>
<div class="form-group">
<label for="Description">Description</label>
<textarea name="description" class="form-control" id="description" ></textarea></div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
In views.py
def index(request):
return render(request, 'index.html')
def create_todo(request):
if request.method == 'POST':
form = listsForm(request.POST)
if form.is_valid():
form.save()
return redirect('index')
In urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
path('create_todo/', views.create_todo, name='create_todo')
]
You will still need to render existed todos, preferably in another template.
So in views.py
def alltodos(request):
todos = Todo.objects.all()
return render(request, 'index.html', {'todos':todos})
In index.html, above form or after it, it doesn't matter, just for clear visibility
<div class="row justify-content-center mt-5">
<div class="col-md-10">
{% if todos %}
<div class="list-group">
{% for todo in todos %}
<a class="list-group-item list-group-item-action><b>{{ todo.title }}</b>{{ todo.description|truncatechars:30 }}{% endif %}</a>
{% endfor %}
</div>
{% else %}
<div class="text-center">
<h2>Looks like you don't have any todos!</h2>
<br>
</div>
{% endif %}
</div>
</div>
In urls.py add
path('todos', views.alltodos, name='alltodos'),
Advanced project of mine
I have find out why it was not working,
I was using <input type="button"> for submit button
but when I changed it to <button type="submit"> it works.

Django form in an extended template

I am very new to Django, I have a home template (home.html) which is extending a base template (base.html) with {% extends "base.html" %}.
base.html containts a contact form.
<form id="email-form" name="email-form" data-name="Email Form" method="post">
{% csrf_token %}
<div>
<label for="Name-2" class="field-label">Full name</label>
{% render_field form.name class+="text-field w-input" %}
</div>
<div>
<label for="Email-2" class="field-label">Email address</label>
{% render_field form.from_email class+="text-field _2 w-input" %}
</div>
<div>
<label for="Phone-2" class="field-label">Phone number</label>
{% render_field form.phone class+="text-field _2 w-input" %}
</div>
<div>
<label for="Timeline" class="field-label">More information</label>
<div>
{% render_field form.message class+="text-field area w-input" %}
</div>
</div>
<div class="algin-center form-actions">
<input type="submit" value="Send Message" data-wait="Please wait..." class="button full w-button">
</div>
</form>
views.py
from django.core.mail import send_mail, BadHeaderError
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render, redirect
from django import forms
class ContactForm(forms.Form):
name = forms.CharField(required=True)
from_email = forms.EmailField(required=True)
phone = forms.CharField(required=True)
message = forms.CharField(widget=forms.Textarea, required=True)
def homeView(request):
if request.method == 'GET':
form = ContactForm()
else:
form = ContactForm(request.POST)
if form.is_valid():
name = form.cleaned_data['name']
phone = form.cleaned_data['phone']
from_email = form.cleaned_data['from_email']
message = form.cleaned_data['message']
try:
send_mail(name, message, from_email, ['email#email.com'])
except BadHeaderError:
return HttpResponse('Invalid header found.')
return redirect('success')
return render(request, "home.html", {'form': form})
The form is rendering fine, however, when I click the submit button nothing happens. I'm guessing this is because the form is not in the homeView directly but through extension, but I have no idea how to fix it, is it possible to have the form in an extended view?

Django file upload: redirect views keep returning errors

I have been working on this music site in Django, basically just trying to get the upload view to work. When you upload a music file, I want it to redirect to the results page. I have been having real trouble with trying to get the redirect to work and it should be very simple but just has not been working. Any help would be greatly appreciated!! My error:
ValueError at /uploads/home/
The view uploads.views.upload didn't return an HttpResponse object. It returned None instead.
uploads/views.py (relevant buggy code):
def upload(request):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return redirect('uploads:results')
else:
form = UploadFileForm()
return render(request, 'uploads/upload.html', {'form': form})
uploads/urls.py
from django.urls import path
from . import views
app_name = 'uploads'
urlpatterns = [
path('home/', views.upload, name='index'),
path('<int:audiofile_id>/results/', views.ResultsView.as_view(), name='results'),
]
upload.html (the upload template)
{% extends 'uploads/base.html' %}
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
{% block content %}
<div class="container">
<div class="row">
<div class="col-lg-12 col-md-8">
{% for audiofile in audiofiles %}
<h1>{{ audiofile.title }}</h1>
</div>
</div>
<div class="row">
<div class="col-lg-12 col-md-8">
<form action="{% url 'uploads:results' audiofile_id %}" method="post" name = "form" enctype = "multipart/form-data">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit">
</form>
{% endfor %}
</div>
</div>
<!--<div class="row">-->
<!-- <div class="col-lg-8">-->
<!--<img src="{% static "uploads/loveLogo.jpg" %}" alt="lovelogo" class="img-fluid">-->
<!-- </div>-->
<!-- </div>-->
</div>
{% endblock %}
you are trying to redirect to the url results but this url also takes the audiofile_id as the parameter which you haven't passed while redirecting so you need to change your view with this :
if form.is_valid():
file = form.save()
return redirect('uploads:results',file.audiofile_id)

My comment system in Django is not working as expected

I'm creating an application where a user can create their own posts, and other users can comment on the posts.
I have already tried retrieving comments from the database, and displaying them for that certain post, however this has been unsuccessful
Here is my code to tackle this problem:
views.py
def comment(request, pk):
form = CommentForm()
comments = Comment.objects.filter(post=pk)
if request.method == 'POST':
form = CommentForm(request.POST)
if form.is_valid():
comment = Comment()
comment.body = form.cleaned_data['body']
comment.user = request.user
comment.post = Post.objects.get(pk=pk)
comment.save()
return redirect('home')
return render(request, 'posts/comments.html')
else:
return render(request, 'posts/comments.html', {'error': 'Please submit valid data'})
else:
return render(request, 'posts/comments.html', {'form': form}, {'comments': comments})
comments.html
{% block content %}
<div class="container">
{% for com in comments.all %}
<p>{{ com.body }}</p>
<br>
{% endfor %}
{% if error %}
{{ error }}
<br>
<br>
{% endif %}
<br>
<br>
<br>
<br>
<br>
<form method="post">
<h2> Comment</h2>
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="btn btn-primary">
Comment</button>
</form>
</div>
{% endblock %}
models.py
class Comment(models.Model):
body = models.CharField(max_length=130)
user = models.ForeignKey(User, on_delete=models.CASCADE)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
def __str__(self):
return self.body
urls.py
path('create/', post_views.Create.as_view(), name='create'),
path('post/<int:pk>/', post_views.DetailPost.as_view(), name='detail'),
path('comment/<int:pk>/', post_views.comment, name='comment'),
urls.py for home
path('admin/', admin.site.urls),
#HOME
path('', post_views.home, name='home'),
This is expected to display a posts comments when a button is pressed to view the post, however the comments do not show. See this here

Update a Profile picture

so i'm working on little django application where users can view and modify there profile ,but i didn't know how to provide a button under the profile picture that allows the user to choose a new one and when he chooses it redirect him to the same page with the new profile picture ,any help or ideas will be usefull , tnks !!
here's what i tried :
forms.py
class picture_form(forms.ModelForm):
class Meta:
model=Profile
fields=('image',)
views.py
def profile(request):
if request.method == 'POST':
form = picture_form(request.POST, request.FILES)
if form.is_valid():
profile = Profile.objects.get(user=request.user)
profile.image = form.cleaned_data['image']
profile.save()
return redirect(reverse('profile'))
else:
for usr in User.objects.all():
if request.user.get_full_name() == usr.get_full_name():
prf = Profile.objects.filter(user=usr)
form = picture_form()
return render(request, 'store/profile.html', {'profile': prf, 'form': form})
template
{% if prf.image %}
<div class="profile-img">
<img src="{{ prf.image.url }}" id="prf_img" alt=""/>
</div>
{% else %}
<div class="profile-img">
<img src="{% static 'img/empty-profile-picture.png' %}" id="prf_img" alt=""/>
</div>
{% endif %}
<!--<a href="{% url 'upload_picture' %}"> <div class="file btn btn-lg " >
Change Photo
<input type="file" name="file"/>
</div></a> -->
<form method="post" action="{% url 'profile' %}" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" class="btn btn-outline-success" value="upload">
</form>
</div>
Django has an awesome generic editing view called UpdateView. You can do something like this:
models.py
class Profile(models.Model):
image = models.ImageField()
views.py
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
from django.views.generic.edit import UpdateView
#method_decorator(login_required, name='dispatch')
class UpdateProfileView(UpdateView):
model = Profile
fields = ['image']
template_name_suffix = '_update_form'
success_url = ''
def form_valid(self, form):
form.instance.user = self.request.user
return super().form_valid(form)
profile_update_form.html
<form method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Update">
</form>
urls.py
from . import views
path('<int:pk>/update/', views.UpdateProfileView.as_view(), name='profile-update')

Categories