Django image upload form not working - html

I am having trouble uploading the image in Django Form.
The following form fails to validate due to some issue in the image uploading
Here is the code :
forms.py
from django import forms
from .models import Description, Bill
class DForm(forms.ModelForm):
class Meta:
model = Description
fields = ('desc', 'billing', 'length', 'quality', 'rate')
class BForm(forms.ModelForm):
party = forms.CharField(widget=forms.TextInput(attrs={'class':'form-control','placeholder':'Party'}))
inovice = forms.FloatField(widget=forms.TextInput(attrs={'class':'form-control','placeholder':'Invoice#'}))
amount = forms.FloatField(widget=forms.TextInput(attrs={'class':'form-control','placeholder':'Bill-Amount'}))
image = forms.ImageField()
image_caption = forms.CharField(widget=forms.TextInput(attrs={'class':'form-control','placeholder':'Description for bill'}))
class Meta:
model = Bill
fields = ('party', 'inovice', 'amount','image','image_caption')
models.py
from __future__ import unicode_literals
#from django.utils.encoding import python_2_unicode_compatible
from django.db import models
##python_2_unicode_compatible
class Description(models.Model):
desc = models.CharField(max_length = 200,default = "Suits")
billing = models.FloatField(max_length = 200)
length = models.FloatField(max_length = 200)
quality = models.CharField( max_length=200,default = "custom")
rate = models.FloatField(max_length = 200)
def __str__(self):
return self.desc
class Bill(models.Model):
party = models.CharField(max_length = 200)
inovice = models.FloatField(max_length = 200)
amount = models.FloatField(max_length = 200)
image = models.ImageField(upload_to='images/products/main',null=True, blank=True)
image_caption = models.CharField(max_length=200,default = "null")
def __str__(self):
return self.party+','+str(self.inovice)+','+str(self.amount)
def bill_id(self):
return self.id;
index.html
{% load staticfiles %}
<!-- test -->
<html>
<head>
<title></title>
<link href="{%static "./styles/bootstrap.min.css" %}" rel="stylesheet" />
</head>
<body>
<h1 style="text-align: center;">Rahul's Shop</h1>
<h2 style="text-align: center;">Inventory</h2>
<form enctype="multipart/form-data" id="bill" action ="{% url 'front:commitbill' %}" method = "post" class="form-horizontal">
{% csrf_token %}
{% for field in form %}
<div class="form-group">
<label for="party" class="control-label col-md-3">{{ field.name }}</label>
<div class="col-md-4">
{{ field }}
</div>
<div class="col-md-5">
<span id="one" style="position:relative; top:5px; color:red "></span>
</div>
</div>
{% endfor %}
<div class="container">
<div class="row">
<input type="button" id="add_items" class="col-md-offset-5 col-md-2 btn btn-success" value="Add items" \>
</div>
</div>
</form>
and views.py
from django.shortcuts import render
from django.http import HttpResponse
from .models import Description, Bill
from django.http import Http404
from .forms import DForm
from .forms import BForm
import pprint
def bill(request):
try:
billinfo = Description.objects.all()
context = {'billinfo': billinfo}
except Description.DoesNotExist:
raise Http404("No Bills")
return render(request, 'front/bill.html', context)
def commitvalues(request):
if request.method == "POST":
form = DForm(request.POST)
if form.is_valid():
Description = form.save()
print Description
return HttpResponse("Hello;You're at the front index.Commit's done!")
print form.errors
return HttpResponse("Fail")
def commitbill(request):
form = BForm()
if request.method == "POST":
form = BForm(request.POST,request.FILES)
if form.is_valid():
Bill = form.save()
return HttpResponse(str(Bill.bill_id()))
else:
print form.errors
form = BForm()
return render(request, 'front/index.html', {
'form': form
})
The print form.errrs returns the following two errors :
<ul class="errorlist"><li>image<ul class="errorlist"><li>This field is required.</li></ul></li></ul>
The forms starts working fine when i remove the image = forms.ImageField() from my forms.py, just the image doesn't uploads, otherwise when i include image = forms.ImageField(), the form never saves due to the above Error

Related

I can submit data but won't go to new page -or- go to new page and data doesn't get saved in Django

So the title kind of says it all. I have a form based on a model. The goal is to have the specific data entered, user presses submit, data gets saved to a Postgresql DB, user sees complete.html. However this is not the case. I can either get the data to save without changing pages, or the page will change but the data will not submit. I have put details on the specifics of I tried below.
urls.py
from django.urls import path, include
from . import views
urlpatterns = [
path('', views.index, name='index-page'),
path('feedback/', views.feedback_view, name = 'feedback'),
path('complete/', views.complete, name = 'complete')
]
models.py
from django.db import models
from django.utils import timezone
from django.core.validators import RegexValidator
class feedback(models.Model):
RECENT_GROUND = [
('PVT','Private'),
('INS','Instrument'),
('COM','Commercial'),
('MEL','Multi-Engine'),
]
RATING = [
(1,'Poor'),
(2,'Below Average'),
(3,'Average'),
(4,'Above Average'),
(5,'Excellent'),
]
id_field = models.AutoField(primary_key = True, serialize = True)
added = models.DateTimeField(default = timezone.now)
spid = models.CharField(primary_key = False, max_length=5, verbose_name = 'Enter the students FSA ID number:')
recent_ground = models.CharField(max_length = 3, choices = RECENT_GROUND, verbose_name = 'Most recently completed ground school:')
question1 = models.IntegerField(choices = RATING, verbose_name = 'This is question 1')
question2 = models.IntegerField(choices = RATING, verbose_name = 'This is question 2')
question3 = models.IntegerField(choices = RATING, verbose_name = 'This is question 3')
question4 = models.IntegerField(choices = RATING, verbose_name = 'This is question 4')
question5 = models.IntegerField(choices = RATING, verbose_name = 'This is question 5')
question6 = models.IntegerField(choices = RATING, verbose_name = 'This is question 6')
question7 = models.IntegerField(choices = RATING, verbose_name = 'This is question 7')
comments = models.TextField(max_length = 500, verbose_name = 'Please leave any additional comments below. If you do not wish to leave comments, type "none".')
def __str__(self):
return self.title
forms.py
#imports forms class from django
from django import forms
#imports the feedback class from ipfeedbackdb/models.py
from ipfeedbackdb.models import feedback
class feedbackForm(forms.ModelForm):
class Meta:
model = feedback
fields = "__all__"
exclude = ['recID','added']
views.py
from django.shortcuts import render
from .forms import feedbackForm as feedform
def index(request):
return render(request, 'index/index.html', {'title':' Home'})
# def feedback(request):
# return render(request, 'index/feedback.html', {'title':' Collection'})
def feedback_view(request):
context = {}
form = feedform(request.POST or None, request.FILES or None)
if form.is_valid():
form.save()
context['form'] = form
return render(request, "index/feedback.html", context)
def complete(request):
return render(request, 'index/complete.html', {'title':' Submitted'})
base.html (removed most of the styling to reduce length)
{% load static %}
<!doctype html>
<html lang="en">
<head>
<link rel="stylesheet" href="{% static 'index/override.css' %}">
{% if title %}
<title>Feedback{{ title }}</title>
{% else %}
<title>Feedback Site</title>
{% endif %}
<script type="text/javascript">
window.history.forward();
function noBack() { window.history.forward(); }
</script>
</head>
<body onload="noBack();" onpageshow="if (event.persisted) noBack();" onunload="">
<div class = 'jumbotron jumbotron-fluid'>
<div class = 'container'>
<h2 class = 'display-4' style = 'color:#fff;margin-left: -100px'>FSA</h2>
<p class = 'lead' style = 'color:#fff;;margin-left: -97px'>Feedback</p>
</div>
</div>
<div>
{% block content %}
{% endblock content %}
</div>
</body>
</html>
index.html
{% extends 'index/base.html' %}
{% block content %}
<div>
<h2>Index Page</h2>
<p>This is some more added text.</p>
</div>
<div>
Next ->
</div>
{% endblock content %}
feedback.html (action = "" saves data without changing pages or clearing form, action ="/feedback/" will save but not clear the form or go to another page. action = "/complete/" took me to complete.html but it did not submit the data to the database.)
{% extends 'index/base.html' %}
{% load crispy_forms_tags %}
{% block content %}
<div>
<h2>Feedback Form Page</h1>
</div>
<div>
<form action = "" method = "post">
{% csrf_token %}
{{ form| crispy }}
<input type="submit" name="Submit">
</form>
</div>
{% endblock content %}
complete.html
{% extends 'index/base.html' %}
{% block content %}
<h2>Your feedback has been submitted. Thank you!</h2>
<div>
Return to start
</div>
{% endblock content %}
In your feedback view, once forms is valid it doesn't go to complete.
def feedback_view(request):
context = {}
form = feedform(request.POST or None, request.FILES or None)
if form.is_valid():
form.save()
return render(request, "index/complete.html", context)
else:
context['form'] = form
return render(request, "index/feedback.html", context)
use button tag!
replace:
<button type="submit">submit</button>
with:
<input type="submit" name="Submit">
change your view like below
views.py:
from django.contrib import messages
from django.shortcuts import redirect
def feedback_view(request):
context = {}
form = feedform(request.POST or None, request.FILES or None)
if request.method == 'POST':
if form.is_valid():
form.save()
return redirect('app_name:url_name') # change to where you want to redirect after a successful from submition
messages.success(request, "Form submitted successfully")
else:
messages.warning(request, form.errors)
context['form'] = form
return render(request, "index/feedback.html", context)

Django: Template Form action not redirecting

My Form action is not redirecting to the passed view. I am calling simple_upload view method from login_form.html form action. Instead, upon clicking the login button, it stays on the same page. Below is my code:
urls.py:
from django.conf.urls import url
from django.contrib import admin
from django.conf import settings
from django.conf.urls.static import static
from uploads.core import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^', views.login_form, name='login_form'),
url(r'^upload/', views.simple_upload, name='simple_upload'),
url(r'^drop_down/$', views.drop_down, name='drop_down'),
url(r'^visualize_view/$', views.visualize_view, name='visualize_view'),
]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.AKASH_ROOT)
login_form.html:
{% block content %}
<button onclick="document.getElementById('id01').style.display='block'" style="width:auto;">Login</button>
<div id="id01" class="modal">
<form class="modal-content animate" action="{% url 'simple_upload' %}" method="get">
{% csrf_token %}
<div class="imgcontainer">
<span class="close" title="Close Modal">×</span>
<img src="https://www.w3schools.com/howto/img_avatar2.png" alt="Avatar" class="avatar">
</div>
<div class="container">
<label for="uname"><b>Username</b></label>
<input type="text" placeholder="Enter Username" name="uname" required>
<label for="psw"><b>Password</b></label>
<input type="password" placeholder="Enter Password" name="psw" required>
<button type="submit">Login</button>
<label>
<input type="checkbox" checked="checked" name="remember"> Remember me
</label>
</div>
<div class="container" style="background-color:#f1f1f1">
<button type="button" class="cancelbtn">Cancel</button>
<span class="psw">Forgot password?</span>
</div>
</form>
</div>
<script>
// Get the modal
var modal = document.getElementById('id01');
// When the user clicks anywhere outside of the modal, close it
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
</script>
{% endblock %}
views.py:
from django.http import HttpResponse
from django.shortcuts import render, redirect
from django.core.files.storage import FileSystemStorage
from .models import Document
from .forms import ExpenseForm
def login_form(request):
return render(request, 'core/login_form.html')
def simple_upload(request):
return HttpResponse("Hello World")
Project hierarchy:
Your home URL pattern is not terminated, so it matches every path. It should be:
url(r'^$', views.login_form, name='login_form'),
It's not good form logic. Forms have valid and invalid actions. If your form is valid you redirect to new (success) page your user, but if not you render same (login) page. But firstly you should give a name your login page like below or use Django's inherit auth urls:
url(r'^login', views.login_form, name='login_form'),
It's my url paths:
from django.contrib import admin
from django.urls import path, include
from . import views
app_name = "user"
urlpatterns = [
path('sign_up/', views.sign_up, name="sign_up"),
path('account_activation_sent/', views.account_activation_sent, name='account_activation_sent'),
path('activate/<uidb64>/<token>/', views.activate, name="activate"),
path('login/', views.login_user, name="login"),
path('logout/', views.logout_user, name="logout"),
path('password_reset/', views.password_reset, name="password_reset"),
path('password_reset/done/', views.password_reset_done, name="password_reset_done"),
path('password_reset/<uidb64>/<token>/', views.password_reset_confirm, name="password_reset_confirm"),
path('password_reset/complete/', views.password_reset_complete, name="password_reset_complete"),
path('profile/<slug:slug>/', views.profile, name="profile"),
]
I wanna show you my simple login function and you will understand:
def login_user(request):
if request.user.is_authenticated:
return redirect("index")
else:
form = LoginForm(request.POST or None)
context = {
"form": form
}
go_to = request.POST.get('next', '/')
print(go_to)
if form.is_valid():
username = form.cleaned_data.get("username")
password = form.cleaned_data.get("password")
user = authenticate(username=username, password=password)
if user is None:
messages.error(request, "Username or password is incorrect! Try again.")
return render(request, "auths/login.html", context)
messages.success(request, "Login successful! Welcome bro.")
login(request, user)
go_to = request.POST.get('next', '/')
if go_to:
go_to = request.POST.get(
'next')
return redirect(go_to)
else:
return redirect("index")
return render(request, "auths/login.html", context)
I use Django's form and It's easy but you can use your custom form in your template. My form is like this:
class LoginForm(forms.Form):
username = forms.CharField(label="Username")
password = forms.CharField(label="Password", widget=forms.PasswordInput)
def __init__(self, *args, **kwargs):
super(LoginForm, self).__init__(*args, **kwargs)
self.fields['username'].label = ''
self.fields['password'].label = ''
class Meta:
model = User
fields = ('username', 'password' )
I hope It will help you.

Django - How to make the topics, that you create public? Learning Log Project

The Problem
I'm trying to make a project, where you can make topics, that can be private or public to unauthenticated users. In every topic, you can then make several entries, applying to that topic. Now I'm trying to make a checkbox in my new_topic.html, where if you check it, it evaluates to True, if not, to False. But I'm having trouble with making the checkbox evaluate to True, when I check it. And for some reason, there is two checkbuttons in the page that applies to new_topic.html; one with a label, and one with just a box.
What I've tried
I've tried recreating the db.sqlite3 database. But that didn't work.
I've tried using request.POST.get('public', False) in my new_topic() function, when saving the new_topic variable.¨
The Code
My learning_logs/models.py looks like this:
from django.db import models
from django.contrib.auth.models import User
class Topic(models.Model):
"""A topic the user is learning about."""
text = models.CharField(max_length=200)
date_added = models.DateTimeField(auto_now_add=True)
public = models.BooleanField(default=False)
owner = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
"""Return a string representation of the model."""
return self.text
class Entry(models.Model):
"""Something specific learned about a topic."""
topic = models.ForeignKey(Topic, on_delete=models.CASCADE)
text = models.TextField()
date_added = models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name_plural = 'entries'
def __str__(self):
"""Return a string representation of the model."""
# Add an ellipsis ONLY if the entry,
# is more than 50 characters long.
if self.text > self.text[:50]:
return self.text[:50] + "..."
elif self.text <= self.text[:50]:
return self.text[:50]
My learning_logs\views.py looks like this:
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponseRedirect, Http404
from django.urls import reverse
from django.contrib.auth.decorators import login_required
from .models import Topic, Entry
from .forms import TopicForm, EntryForm
def index(request):
"""The Home Page for Learning Log."""
return render(request, 'learning_logs/index.html')
def check_topic_owner(request, topic):
"""Checks if the topic requested, is requested by the owner.
Else return Http404.
"""
if topic.owner != request.user:
raise Http404
#login_required
def topics(request):
"""Show all topics."""
topics = Topic.objects.filter(owner=request.user).order_by('date_added')
context = {'topics': topics}
return render(request, 'learning_logs/topics.html', context)
#login_required
def topic(request, topic_id):
"""Show a single topic and all its entries."""
topic = get_object_or_404(Topic, id=topic_id)
# Make sure the Topic belongs to the current user.
check_topic_owner(request, topic)
entries = topic.entry_set.order_by('-date_added')
context = {'topic': topic, 'entries': entries}
return render(request, 'learning_logs/topic.html', context)
#login_required
def new_topic(request):
"""Add a new topic."""
if request.method != 'POST':
# No data submitted; create a blank form.
form = TopicForm()
else:
# POST data submitted; process data.
form = TopicForm(data=request.POST)
if form.is_valid():
new_topic = form.save(commit=False)
new_topic.owner = request.user
new_topic.save()
return HttpResponseRedirect(reverse('learning_logs:topics'))
context = {'form': form}
return render(request, 'learning_logs/new_topic.html', context)
#login_required
def new_entry(request, topic_id):
"""Add a new entry for the particular topic."""
topic = get_object_or_404(Topic, id=topic_id)
check_topic_owner(request, topic)
if request.method != 'POST':
# No data submitted; create a blank form.
form = EntryForm()
else:
# POST data submitted; process data.
form = EntryForm(data=request.POST)
if form.is_valid():
new_entry = form.save(commit=False)
new_entry.topic = topic
if new_entry.topic.owner == request.user:
new_entry.save()
else:
return Http404
return HttpResponseRedirect(reverse('learning_logs:topic',
args=[topic_id]))
context = {'topic': topic, 'form': form}
return render(request, 'learning_logs/new_entry.html', context)
#login_required
def edit_entry(request, entry_id):
"""Edit an existing entry."""
entry = get_object_or_404(Entry, id=entry_id)
topic = entry.topic
check_topic_owner(request, topic)
if request.method != 'POST':
# Initial request; pre-fill form with the current entry.
form = EntryForm(instance=entry)
else:
# POST data submitted; process data.
form = EntryForm(instance=entry, data=request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse('learning_logs:topic',
args=[topic.id]))
context = {'entry': entry, 'topic': topic, 'form': form}
return render(request, 'learning_logs/edit_entry.html', context)
My learning_logs\forms.py looks like this:
from django import forms
from .models import Topic, Entry
class TopicForm(forms.ModelForm):
class Meta:
model = Topic
fields = ['text']
labels = {'text': ''}
class EntryForm(forms.ModelForm):
class Meta:
model = Entry
fields = ['text']
labels = {'text': ''}
widgets = {'text': forms.Textarea(attrs={'cols': 80})}
My learning_logs\templates\learning_logs\new_topic.html looks like this:
{% extends "learning_logs/base.html" %}
{% load bootstrap3 %}
{% block header %}
<h2>New topic:</h2>
{% endblock header %}
{% block content %}
<h1>Add a new topic:</h1>
<form action="{% url 'learning_logs:new_topic' %}" method='post'
class="form">
{% csrf_token %}
{% bootstrap_form form %}
<div class="form-check">
<input class="form-check-input" type="checkbox" value=True id="public">
<label class="form-check-label" for="public">
Make it public?
</label>
</input>
</div>
{% buttons %}
<button name="submit" class="btn btn-primary">Add Topic</button>
{% endbuttons %}
</form>
{% endblock content %}
I just can't seem to fix this error. Thanks in advance! Any help is appreciated.
You have:
<input class="form-check-input" type="checkbox" value=True id="public">
<label class="form-check-label" for="public">
Make it public?
</label>
</input> # <<< this closing tag is wrong
correct input tag :
<input class="form-check-input" type="checkbox" value=True id="public" />
So you'll have:
<label class="form-check-label" for="public">
Make it public?
</label>
<input class="form-check-input" type="checkbox" value=True id="public" />

form field not showing (django 1.7)

The form field (text area) is not showing in my django template. I can figure out where the problem is.
Views.py
class Profile(View):
"""User Profile page reachable from /user/<username> URL"""
def get(self, request, username):
params = dict()
user = User.objects.get(username=username)
tweets = Tweet.objects.filter(user=user)
params["tweets"] = tweets
params["user"] = user
return render(request, 'profile.html', params)
class PostTweet(View):
"""Tweet Post form available on page /user/<username> URL"""
def post(self, request, username):
if request.method == 'GET':
form = TweettForm()
else:
form = TweetForm(self.request.POST)
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()
words = form.cleaned_data['text'].split(" ")
for word in words:
if word[0] == "#":
hashtag, created = HashTag.objects.get_or_create(name=word[1:])
hashtag.tweet.add(tweet)
return HttpResponseRedirect('/user/'+username)
return render(request, 'profile.html', {'form': form})
forms.py
from django import forms
class TweetForm(forms.Form):
text = forms.CharField(widget=forms.Textarea(attrs={'rows': 1, 'cols':85}), max_length=160)
country = forms.CharField(widget=forms.HiddenInput())
profile.html
{% extends "base.html" %}
{% block content %}
<div class="row clearfix">
<div class="col-md-12 column">
<form method="post" action="post/">{% csrf_token %}
<div class="col-md-8 col-md-offset-2 fieldWrapper">
{{ form.text.errors }}
{{ form.text }}
</div>
{{ form.country.as_hidden }}
<div>
<input type="submit" value="post">
</div>
</form>
</div>
urls.py
from django.conf.urls import patterns, include, url
from django.contrib import admin
from tweets.views import Index, Profile, PostTweet
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())
)
Only the submit (post) button shows on the on when rendered in the browser. The text are is not there
You get nothing since you are not passing the form to the template. Write get function in PostTweet view and include form = TweetForm() in it as a param passed to the template.

Uploading A file in django with ModelForms

I have been hacking away at this project for many hours now and just cannot figure out how to create a simple file upload app. I have looked at all the tutorials but none quite apply to my situation and i just cant get the code right. I know the code I have at this point wont run but I was hoping somone might be able to push me in the right direction with what I have. I know its not great but Im getting frustrated and I hope someone could help especially with my views.py Thank you so much. Thank you in advance!
Models.py
from django.db import models
from django.contrib.auth.models import User
from django.forms import ModelForm
class WorkSheet(models.Model):
worksheet_name = models.CharField(max_length= 150, default = True)
creator = models.ForeignKey(User, default = True)
worksheet_file = models.FileField(upload_to = 'worksheets', default = True)
number_of_stars = models.PositiveIntegerField(default = True)
category = models.CharField(max_length = 100, default = 0)
class UploadWorkSheetForm(ModelForm):
class Meta:
model = WorkSheet
Views.py
from django.shortcuts import render, render_to_response, HttpResponseRedirect
from django.conf import settings
from django import http
from models import WorkSheet
from forms import UploadWorkSheetForm
def upload(request):
template = 'upload.html'
if request.method == 'POST':
if 'file' in request.FILES:
file = request.FILES['file']
filename = file['filename']
fd = open('%s/%s' % (settings.MEDIA_ROOT, filename), 'wb')
fd.write(file['content'])
fd.close()
return http.HttpResponseRedirect('upload_success.html')
else:
form = UploadWorkSheetForm()
return render_to_response(template, {'form': form})
return render(request, 'upload.html', {'form': form})
Upload.html
<!DOCTYPE html>
<html>
<head>
<title>WSD Upload</title>
</head>
<body>
<h1>Upload WorkSheet</h1>
{% block body %}
<form action="." method="post" enctype="multipart/form-data"> {{ form }}
<type="submit" value = "Upload"/>
</form>
{% endblock %}
</body>
</html>
If there is anything else you need please tell me. Thank you thank you thank you!
views.py
def upload(request):
template = 'upload.html'
if request.method == 'POST':
form = UploadWorkSheetForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return HttpResponseRedirect('upload_success.html') <---change this to your valid url not template name
else:
form = UploadWorkSheetForm()
return render(request, 'upload.html', {'form': form})
template
...................
{% block body %}
<form action="." method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value = "Upload"/>
</form>
{% endblock %}
....................