WTForms Flask: form_name.field_name.data = None - flask-wtforms

I'm very early into learning Flask/WTForms, and I'm wondering why I keep getting None for form_name.field_name.data
application.py:
import os
from flask import Flask, session, render_template, request, redirect, url_for
from flask_session import Session
from wtforms import Form, PasswordField, StringField, SelectField, validators
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
app = Flask(__name__)
# Create registration form class
class RegistrationForm(Form):
username = StringField("Username")
password = PasswordField("Password")
name = StringField("Name")
email = StringField("Email Address")
city = StringField("Nearest City")
#app.route("/", methods=["GET", "POST"])
def signup():
registration_form = RegistrationForm()
if request.method == "GET":
return render_template("index.html", registration_form=registration_form)
else:
username = registration_form.username.data
password = registration_form.password.data
name = registration_form.name.data
email = registration_form.email.data
city = registration_form.city.data
# print for testing
print(registration_form.data)
print(username)
print(password)
print(name)
print(email)
print(city)
user = {
"username": registration_form.username.data,
"password": registration_form.password.data,
"name": registration_form.name.data,
"email": registration_form.email.data,
"city": registration_form.city.data
}
return render_template("success.html", user=user)
index.html:
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Index</title>
</head>
<body>
<h1>Index</h1>
<form action="/" method="POST">
<ul>
{% for field in registration_form %}
<li>{{ field.label }}: {{ field }}</li>
{% endfor %}
<li><input type="submit"></li>
</ul>
</form>
</body>
</html>
print(registration_form.data) prints {'username': None, 'password': None, 'name': None, 'email': None, 'city': None}, but I expect the user-input values instead of None.
Similarly, each of these prints print None, and I expect the user-input values.
print(username)
print(password)
print(name)
print(email)
print(city)

Related

Flask-WTForms .validate_on_submit() never executes

So basically I want to have a Updateform() form that allows users to update their account details. All my other forms (register, etc.) work perfectly fine but this specific form never validates on submit. Hence when I press the submit button the page just refreshes but the .validate_on_submit() code doesn't execute.
I've looked through the forums and a common issue I found is the .CSRF token missing, but I'm using form.hidden_tag() which I read should work perfectly fine. So it seems that my issue is unique.
I've been looking on the forums for hours but haven't found a solution.
Here is my form code:
class Updateform(FlaskForm):
email = StringField('Email:', validators=[DataRequired(), Email()])
picture = FileField('Update Profile Picture:', validators=[FileAllowed(['jpg', 'png'])])
submit = SubmitField("Update")
def validate_email(self, email):
if email.data != User.email:
if User.query.filter_by(email=email.data).first():
raise ValidationError('Email has already been registered')
Here is the route:
#users.route('/account', methods=['GET', 'POST'])
#login_required
def account():
form = Updateform()
print("hello")
if form.validate_on_submit():
print(form)
print("YES!!!")
name = current_user.name
pic = add_profile_pic(form.picture.data, name)
current_user.profile_image = pic
current_user.email = form.email.data
db.session.commit()
flash("Account Updated")
# elif request.method == "GET":
# form.email = current_user.email
profile_image = url_for('static', filename='profile_pics/'+current_user.profile_image)
return render_template('account.html', profile_image=profile_image, form=form)
And here is the html code:
{% extends "base.html" %}
{% block content %}
<div align="center">
Hi {{ current_user.name }}<br>
<img align="center" src="{{ url_for('static', filename='profile_pics/'+current_user.profile_image) }}">
</div>
<div class="container">
<form method="post">
{{ form.hidden_tag() }}
<div class="form-group">
{{ form.email.label(class='form-group') }}
{{ form.email(class='form-control') }}
</div>
<div class="form-group">
{{ form.picture.label(class='form-group') }}
{{ form.picture(class='form-control') }}
</div>
<div class="form-group">
{{ form.submit() }}
</div>
</form>
</div>
{% endblock %}
The extra classes you see are from the bootstrap library incase anyone is wondering.
Hello you could find out what the problem is by adding a else for you if form.validate_on_submit(): and have it do this
for error in form.email.errors:
print(error)
for error in form.picture.errors:
print(error)
this should tell you what is not working hope this helps and I have not tested this so it could have typos

Django FilteredSelectMultiple Right Half Does Not Render

I have the same problem as [#DHerls][1], but the given solution did not work for me.
Django FilteredSelectMultiple not rendering on page
Other similar questions with solutions I tried:
Django FilteredSelectMultiple widget rendered with bootstrap
Django admin's filter_horizontal not working
Uncaught ReferenceError: django is not defined
The problem is that only half of the FilteredSelectMultiple shows up:
Things I have tried:
syncdb
checking that jQuery is running
checked for jQuery imports conflicting, but I am new to
it, so I am unsure about this.
template.html
{{ form.media }}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="{% static 'js/bootstrap.js' %}"></script>
<script src="{% static '/admin/js/jquery.init.js' %}"></script>
<script src="{% static '/js/SelectBox.js' %}"></script>
<script src="{% static '/js/SelectFilter2.js' %}"></script>
<link href="https://fonts.googleapis.com/css?family=Playfair+Display+SC" rel="stylesheet">
<link rel="shortcut icon" type="imgs/favicon.png" href="{% static 'imgs/favicon.png' %}"/>
[...]
<form action="{% url 'recipes' %}" id="add_ingredient" method="post" accept-charset="utf-8" style="width: 400px; margin-left: auto; margin-right: auto; padding: 10px 0 30px 0;" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<span class="input-group-btn">
<button class="btn btn-secondary" style="margin-left: 40%; margin-top: 20px; padding: -10px;" type="submit">Submit</button>
</span>
</form>
views.py
decorators = [login_required, transaction.atomic]
#method_decorator(decorators, name='dispatch')
class RecipeCreate(CreateView):
model = Recipe
form_class = RecipeCreateForm
template_name = 'sous/new_recipe.html'
def get_context_data(self, **kwargs):
context = super(RecipeCreate, self).get_context_data(**kwargs)
context['form'] = RecipeCreateForm()
return context
def form_valid(self, form):
self.object = form.save()
return render(self.request, 'sous/new_recipe.html', {'new_recipe': self.object })
forms.py
class RecipeCreateForm(forms.ModelForm):
name = forms.CharField(max_length=150, required=True, widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': '*' }))
photo = forms.ImageField(required=False, widget=forms.FileInput(attrs={'class': 'form-control'}))
cost = forms.DecimalField(required=False, min_value=0, max_digits=5, decimal_places=2, widget=forms.NumberInput(attrs={'step': 0.01, 'class': 'form-control', 'placeholder': '00.00'}))
prep_time = forms.DurationField(required=False, widget=forms.NumberInput(attrs={'step': 0.01, 'class': 'form-control', 'placeholder': 'HH.MM'}))
cook_time = forms.DurationField(required=False, widget=forms.NumberInput(attrs={'step': 0.01, 'class': 'form-control', 'placeholder': 'HH.MM'}))
ingredients = forms.ModelMultipleChoiceField(queryset=Ingredient.objects.all(), widget=FilteredSelectMultiple('Ingredient', is_stacked=False, attrs={'rows':'5'}))
class Meta:
model = Ingredient
ordering = ('order',)
fields = ['ingredients', 'name', 'cost', 'prep_time', 'cook_time', 'photo']
css = {
'all':('/admin/css/widgets.css', 'admin/css/overrides.css'),
}
js = ('/admin/jsi18n/',)
def __init__(self, parents=None, *args, **kwargs):
super(RecipeCreateForm, self).__init__(*args, **kwargs)
Using django 2.2, I was able to solve this by putting this in my
urls.py
urlpatterns = [
...
...
/* all your urls */
re_path(r'^jsi18n/$', JavaScriptCatalog.as_view(), name='javascript-catalog')
]
bottom of template
<script type="text/javascript" src="{% url 'javascript-catalog' %}"></script>
forms.py
class ManageUserPermissionsForm(forms.ModelForm):
class Meta:
model = User
fields = ['permissions']
permissions = forms.ModelMultipleChoiceField(queryset=Permission.objects.all(),required=True,
widget=FilteredSelectMultiple('User Permissions',is_stacked=False))
class Media:
css = {'all': ('/static/admin/css/widgets.css',), }
views.py (you can ignore permissions required mixin, and slug_field and slug_url_kwarg
class ManageUserPermissionsView(PermissionRequiredMixin, UpdateView):
permission_required = 'manage_user'
model = User
form_class = ManageUserPermissionsForm
template_name = 'manage_permissions.html'
slug_field = 'uuid'
slug_url_kwarg = 'uuid'
I made this specifically for managing user permissions, but the queryset can be whatever you want

How do I apply flex wrap to this django template

I was inquiring about how to apply flex-wrap to the pictures in the template so that they are evenly distributed throughout the page and not in a column-like structure like in the current situation.
I want the images in the 2nd template (blue-background) to align like the ones with white background. The code I have provided with the question created the 2nd template.
Here is the template code:
<DOCTYPE = html>
<html lang ="en">
<header>
{% block sidebar %}
<ul class = "sidebar">
<li>Articles</li>
<li>Create Article</li>
</ul>
{% endblock %}
</header>
<body>
<style>
body{
display:flex;
justify-content:space-around;
text-align: center;
background-color: lightblue;
}
.page{
display:flex;
flex-wrap:wrap;
align-content:space-between;
width:400px;
text-align: center;
margin:10px auto 20px auto;
background-color: rgba(47,47,47,0.98);
font-color:white;
border-radius: 16px;
}
.sidebar{
display:flex;
justify-content:space-around;
flex-direction:column;
float:left;
width:200px;
border:1px solid #000;
}
.pic{
display:flex;
flex-wrap:wrap;
/*justify-content:space-around;*/
/*align-content:space-between;*/
}
</style>
{% block content %}
<h2>Language is:{{language}}</h2>
enter code here
<h2> Session Language is:{{session_language}}</h2>
{% if articles.count > 0 %}
{% for article in articles %}
<div class = "page">
<h2><a href ='/article/get/{{article.id}}/'>{{article.title}}</a></h2>
</div>
<div class ="pic">
{% if article.thumbnail %}
<p><img class ="pic" img src = "/static/{{article.thumbnail}}/" width = " "200"/></p>
{% endif %}
</div>
<p>{{article.bod|lower|truncatewords:"10"}}</p>
</div>
{% endfor %}
{% endif %}
<p>End Of Page</p>
{% endblock %}
</body>
</html>
VIEWS.PY
from django.shortcuts import render_to_response
from article.models import Article
from django.http import HttpResponse
from forms import ArticleForm
from django.http import HttpResponseRedirect
from django.core.context_processors import csrf
def articles(request):
language = 'en-gb'
session_language = 'en-gb'
if 'lang' in request.COOKIES:
language = request.COOKIES['lang']
if 'lang' in request.session:
session_language = request.session['lang']
return render_to_response('articles.html',
{'articles' :Article.objects.all(),
'language': language,
'session_language': session_language})
def article(request, article_id = 1):
return render_to_response ('article.html',
{'article': Article.objects.get(id = article_id)})
def language(request, language = 'en-gb'):
response = HttpResponse("setting language to %s" % language)
response.set_cookie("lang", language)
request.session["lang"] = language
return response
def create(request):
if request.POST:
form = ArticleForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return HttpResponseRedirect("/article/all")
else:
form = ArticleForm()
args = {}
args.update(csrf(request))
args["form"] = form
return render_to_response("Create_Article.html",args)
def like_article(request, article_id):
if article_id:
a = Article.objects.get(id = article_id)
count = a.likes
count += 1
a.likes = count
a.save()
return HttpResponseRedirect('/article/get/%s' % article_id)
URLS.PY
from django.conf.urls import patterns, include, url
from django.contrib import admin
from django.views.debug import default_urlconf
from . import views
admin.autodiscover()
urlpatterns = [
url(r'^all/$', 'article.views.articles', name = 'articles'),
url(r'^create/$', 'article.views.create', name = 'create'),
url(r'^language/(?P<language>[a-z\-]+)/$', 'article.views.language', name = 'language'),
url(r'^get/(?P<article_id>\d+)/$', 'article.views.article', name = 'article'),
url(r'^like/(?P<article_id>\d+)/$','article.views.like_article'),
#(r'^$', default_urlconf),
]
MODELS.PY
from django.db import models
from time import time
def get_upload_file_name(instance, filename):
return "uploaded_files/%s_%s" % (str(time()).replace(' . ', '_') , filename)
"Create your models here"
class Article(models.Model):
title = models.CharField(max_length = 200)
body = models.TextField()
pub_date = models.DateTimeField("date published")
likes = models.IntegerField(default = 0)
thumbnail = models.FileField(upload_to = get_upload_file_name)
def __unicode__(self):
return self.title
class Comment(models.Model):
name = models.CharField(max_length = 200)
body = models.TextField()
pub_date = models.DateTimeField("date published")
article = models.ForeignKey(Article)
FORMS.PY
from django import forms
from models import Article, Comment
class ArticleForm(forms.ModelForm):
class Meta:
model = Article
fields = ("title", "body", "pub_date" ,"thumbnail")
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ("name","body","pub_date")
SETTINGS.PY
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
DEBUG = True
TEMPLATE_DEBUG = True
ALLOWED_HOSTS = []
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
#'django.contrib.auth.middleware.AuthenticationMiddleware'
#'django.contrib.messages.middleware.MessageMiddleware'
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'article',
)
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
#'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
ROOT_URLCONF = 'brn.urls'
WSGI_APPLICATION = 'brn.wsgi.application'
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'C:/Users/BRIN/Bitnami Django Stack projects/brn/brn/goblin.db',
}
}
EXAMPLE_DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
STATIC_URL = '/static/'
MEDIA_ROOT = "C:/Users/BRIN/Bitnami Django Stack projects/brn/static/"
MEDIA_URL = '/media/'
TEMPLATE_DIRS = "C:/Users/BRIN/Bitnami Django Stack projects/brn/static/html/",
STATIC_URL = '/static/html/'
STATICFILES_DIRS =(
"C:/Users/BRIN/Bitnami Django Stack projects/brn/static/html/",
)
'STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
#'django.contrib.staticfiles.finders.DefaultStorageFinder',
)
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
'django.template.loaders.eggs.Loader',
)

Django Crispy Forms, Bootstrap, helper.label_class and helper.field_class not working

I have a problem with the crispy forms framework, setting the field_class and label_class attributes is not making a difference to the layout. I am using Bootstrap3, and all of the css files can be used elsewhere on my site (ie they are being picked up successfully in the static directory).
forms.py
class LoginForm(forms.Form):
username = forms.CharField()
password = forms.CharField(widget=forms.PasswordInput)
helper = FormHelper()
helper.form_class = 'form-horizontal'
helper.label_class = 'col-lg-2'
helper.field_class = 'col-lg-10'
helper.layout = Layout(
'username',
'password',
Submit('submit', 'Log Me In', css_class='btn btn-success'),
)
login.html
{% extends "base.html" %}
{% load crispy_forms_tags %}
{% block content %}
{% crispy form %}
{% endblock %}
Upon inspecting element in my browser, the col-lg-2 and col-lg-10 CSS classes are simply NOT being applied to the labels and fields respectively...
You should place all the helper logic under the __init__ method:
class LoginForm(forms.Form):
username = forms.CharField()
password = forms.CharField(widget=forms.PasswordInput)
def __init__(self, *args, **kwargs):
super(LoginForm, self).__init__(self, *args, **kwargs)
self.helper = FormHelper()
self.helper.form_class = 'form-horizontal'
self.helper.label_class = 'col-lg-2'
self.helper.field_class = 'col-lg-10'
self.helper.layout = Layout(
'username',
'password',
Submit('submit', 'Log Me In', css_class='btn btn-success'),
)

Django tables2 and css

I've got a table in a view which doesn't render css. I suppose it's a stupid error but I can't find any solution on my way :(
The View :
class ContactsTable(tables.Table):
selection = tables.CheckBoxColumn(accessor="id")
class Meta:
model = Contact
exclude = ("id", "civilite", "ad1", "ad2", "cp")
sequence =("selection", "nom", "prenom", "comments", "telport", "telfixe", "email", "ville", "regime")
def ListContacts(request):
table = ContactsTable(Contact.objects.all())
RequestConfig(request).configure(table)
return render(request, "contacts/contact_list.html", {'table': table})
The Template :
{% load render_table from django_tables2 %}
<html>
<head>
<link rel="stylesheet" href="{{ STATIC_URL }}django_tables2/themes/paleblue/css/screen.css" />
</head>
<body>
{% render_table table %}
</body>
</html>
Sorry for my poor english and noobie question.
For anyone who has the same problem, don't forget the attrs...
class ContactsTable(tables.Table):
class Meta:
model = Contact
exclude = ("id", "civilite", "ad1", "ad2", "cp")
sequence =("selection", "nom", "prenom", "comments", "telport", "telfixe", "email", "ville", "regime")
--> attrs = {"class": "paleblue"} <--
selection = tables.CheckBoxColumn(accessor="id")

Resources