UNIQUE constraint failed in sqlalchemy when trying to update database - sqlite

I keep getting UNIQUE constraint failed when trying to update data in my database. I am using username as the primary_key, but this code works just fine when I construct an object and add it to the database in the terminal. It is only when I try it in my views.py that I have issues.
Here is the error
IntegrityError: (sqlite3.IntegrityError) UNIQUE constraint failed: mobility.username [SQL: u'INSERT INTO mobility (username, cc_letter, sabc_cbt) VALUES (?, ?, ?)'] [parameters: (u'pass', u'tt', None)]
File "/home/jsnyder10/Documents/45/app/views.py", line 57, in mobility_edit_user
db.session.commit()
views.py - this is the one causing issue at db.session.commit()
#app.route('/mobility_edit_user', methods=['GET', 'POST'])
#login_required
def mobility_edit_user():
#build user list
data=User.query.with_entities(User.username).all()
users=[]
for i in data:
users.append(i[0])
form=MobilityForm(request.form)
if request.method == "POST":
if request.form['submit']=='SelectUser':
#moves selected user to front of form to persist with next call
users.insert(0, users.pop(users.index(request.form.get('user'))))
data=Mobility.query.filter_by(username=request.form.get('user')).first()
#form.populate_obj(data)
form=MobilityForm(obj=data)
flash("Selected User " + request.form.get('user'))
elif request.form['submit']=='Update' and form.validate():
print("validated")
u=Mobility()
form.populate_obj(u)
u.username=request.form.get('user')
db.session.add(u)
print("added")
db.session.commit()
flash("Updated User" + request.form.get('user'))
else:
#move selected user to front of form
users.insert(0, users.pop(users.index(request.form.get('user'))))
data=Mobility.query.filter_by(username=request.form.get('user')).first()
form=MobilityForm(obj=data)
flash("Form not validated")
elif request.method == "GET":
form=MobilityForm(request.form)
flash("GET")
return render_template('mobility_edit_user.html',title='Mobility Edit User',
form=form, users=users)
models.py
class MobilityForm(ModelForm):
class Meta:
model=Mobility
forms.py
class MobilityForm(ModelForm):
class Meta:
model=Mobility
mobility_edit_users.html
<!-- extend base layout -->
{% extends "base.html" %}
{% block content %}
{% from "_formhelpers.html" import render_field %}
{% include 'flash.html' %}
<div class="well">
<form class="form-horizontal" action="" method="post" name="edit">
<div class="control-group">
<input class="btn btn-primary" type="submit" name="submit" value="SelectUser">
<input class="btn btn-primary" type="submit" name="submit" value="Update">
</div>
<div class="control-group">
<select name="user">
{% for user in users %}<option value={{ user }}>{{ user }}</option>{% endfor %}
</select>
</div>
<table border="1" cellpadding="5" cellspacing="5" width="100%" style="background color:white">
{% for attr, value in form._fields.iteritems() %}
<tr>
<th>{{ attr }}</th>
<td>{{ value }}</td>
</tr>
{% endfor %}
</table>
</form>
</div>
{% endblock %}

Related

custom size of field in crispy form django not working

i want to display a form to create posts. i use crispy-form and it currently displays:
with html template:
{% extends 'blog_app/base.html' %}
{% load crispy_forms_tags %}
{% block content %}
<div class="content-section">
<form method="POST">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Create Post</legend>
{{ form.media }}
{{ form|crispy }}
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" type="submit">Post</button>
</div>
</form>
</div>
{% endblock %}
i want to increase size of the title box and reduce size of the content box so that i fits the content section.
what i tried:
in template, display each field as crispy field with specified css class:
{% block content %}
<div class="content-section">
<form method="POST">
{% csrf_token %}
<div class="form-group col-md-8">
{{ form.title|as_crispy_field }}
</div>
<div class="form-group col-md-8">
{{ form.content|as_crispy_field }}
</div>
<div class="form-group">
<button class="btn btn-outline-info" type="submit">Post</button>
</div>
</form>
</div>
{% endblock %}
in form class, set helper and layout:
class PostCreateForm(forms.ModelForm):
class Meta:
model = Post
fields = ['title', 'content']
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper()
self.layout = Layout(
Field('title', id="form-title", css_class="col-md-8", name="title"),
Field('content', id="form-content", css_class="col-md-8", name="title"))
in both ways, nothing changes.
can someone give me a pointer?
update:
for the content box, since i used RichTextField from ckeditor for it, when i add the below config to settings.py, the size of it does change to fit the content section. but i still have no idea how to change size of the title box.
CKEDITOR_CONFIGS = {
'default': {
'height': '100%',
'width': '100%',
},
}
Ensure that you have the correct template pack in your settings.py:
CRISPY_TEMPLATE_PACK = 'bootstrap4'
...and use your columns and rows in the layout (in the form helper, not directly in the form):
from crispy_forms.layout import Layout, HTML, Row, Column
class PostCreateForm(forms.ModelForm):
class Meta:
model = Post
fields = ['title', 'content']
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.layout = Layout(
Row(
Column(
'title',
css_class='col-md-8'
),
),
Row(
Column(
'content',
css_class='col-md-8'
),
)
)
Next, use the crispy templatetag:
<form method="POST">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Create Post</legend>
{{ form.media }}
{% crispy form %}
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" type="submit">Post</button>
</div>
</form>

FlaskForm inserting null values into db despite DataReguired

I have a Flask form and it adds entries into db without issues.
However, when I click 'submit' on the empty form, it adds null entries. I already have limitation set to 'DataRequired'. What else do I need to stop this from happening?
My form:
class AddNoteForm(FlaskForm):
note = StringField('Note',[DataRequired()])
add = SubmitField('Add Note')
My model:
class Note(db.Model):
id = db.Column(db.Integer,primary_key = True)
note = db.Column(db.String(150),nullable = False)
date_added = db.Column(db.DateTime,default = datetime.utcnow)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
My routes.py:
#routes.route('/userpage',methods=['GET','POST'])
#login_required
def userpage():
print('page start')
session.get("current_user")
user_notes = Note.query.filter_by(user_id = current_user.id)
if request.method == "POST":
print('method is post')
if current_user.is_authenticated:
print ('user in session')
note = Note(note = request.form.get('addnote'), user_id = current_user.id)
db.session.add(note)
db.session.commit()
return render_template('userpage.html', note=note, user_notes=user_notes)
else:
print('user not in session"')
return render_template('userpage.html')
return render_template('userpage.html', user_notes=user_notes)
my form-html:
{% extends 'base.html' %}
{% block body %}
<p>Welcome {{ current_user.name }}</p>
<br>
<form method='post'>
<table>
<tr>
<td></td> <input type="text", name ="addnote", placeholder="Add note"/>
</tr>
</table>
<input class ="button" , type="submit" />
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
<p>
{% for item in user_notes %}
<li class = "diary"> {{ item.note }}</li>
{% endfor %}
</p>
</form>
{% endblock %}

How can I set the class of a checkbox label with wtforms?

I would like to use Bootstrap 4 forms. This means I need to add the class form-check-label to the label of a checkbox. How can I do that?
Minimal Code Sample
requirements.txt
Flask==1.0.2
WTForms==2.2.1
Flask-WTF==0.14.2
app.py:
from flask import Flask, render_template
from flask_wtf import FlaskForm
from wtforms import BooleanField, StringField, PasswordField, SubmitField
app = Flask(__name__, template_folder="templates")
app.config['SECRET_KEY'] = 'http://flask.pocoo.org/docs/1.0/quickstart/#sessions'
class LoginForm(FlaskForm):
username = StringField('Username')
password = PasswordField('Password')
remember_me = BooleanField("Remember Me")
submit = SubmitField('Submit')
#app.route('/')
def index():
form = LoginForm()
return render_template('login.html', form=form)
app.run()
templates/login.html:
<form action="" method="post" class="form form-horizontal" role="form">
{{ form.hidden_tag() }}
<div class="form-group">
{{ form.username.label }}<br>
{{ form.username(size=32, class_="form-control") }}<br>
{% for error in form.username.errors %}
<span style="color: red;">[{{ error }}]</span>
{% endfor %}
</div>
<div class="form-group">
{{ form.password.label }}<br>
{{ form.password(size=32, class_="form-control") }}<br>
{% for error in form.password.errors %}
<span style="color: red;">[{{ error }}]</span>
{% endfor %}
</div>
<div class="form-check">
{{ form.remember_me.label }}<br> # form-check-label
{{ form.remember_me(value='n', class_="form-check-input") }}
{% for error in form.remember_me.errors %}
<span style="color: red;">[{{ error }}]</span>
{% endfor %}
</div>
{{ form.submit(class_="btn btn-primary") }}
</form>
The solution turned out to be super simple - I can call .label also as a function identical to the other elements:
{{ form.remember_me.label(class_="form-check-label") }}

How to send information on my email from django form? - Django 2

How to send information on my email from django form. Now I can see information only in my console output on my cmd
template:
{% extends 'base.html' %}
{% load widget_tweaks %}
{% block title %}
Contact Us
{% endblock %}
{% block content %}
<h2 class="mt-4 ml-4">Contact Me</h2>
<form method="post">
<div class="container mt-4">
{% csrf_token %}
<div class="col-md-4">
{{ form.subject.label }}
{% render_field form.subject class+="form-control" %}
</div>
<div class="col-md-4">
{{ form.email.label }}
{% render_field form.email type="email" class+="form-control" %}
</div>
<div class="col-md-4">
{{ form.message.label }}
{% render_field form.message class+="form-control" rows="4" cols="6" %}
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary mt-2 ml-3">Send</button>
</div>
</div>
</form>
{% endblock %}
forms.py:
from django import forms
class ContactForm(forms.Form):
email = forms.EmailField(required=True)
subject = forms.CharField(required=True)
message = forms.CharField(widget=forms.Textarea, required=False)
views.py:
from django.core.mail import send_mail, BadHeaderError
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render, redirect
from .forms import ContactForm
def emailView(request):
if request.method == 'GET':
form = ContactForm()
else:
form = ContactForm(request.POST)
if form.is_valid():
subject = form.cleaned_data['subject']
email = form.cleaned_data['email']
message = form.cleaned_data['message']
try:
send_mail(subject, message, email, ['yarik.nashivan#gmail.com'])
except BadHeaderError:
return HttpResponse('Invalid header found.')
return redirect('success')
return render(request, "email.html", {'form': form})
def successView(request):
return HttpResponse('Success! Thank you for your message. <p>You will be redirected to the main page in 3 seconds.</p> <meta http-equiv="refresh" content="3;url=/"> ')
Don't look at it: fgkjdfldfjgndfkgndfskj vdafk kjdsjaf jjjfd jdsaf dj fdsjn dnjndfj jdffjk hdsffdfgfdb sfdf
Well, you are using console backend, that is why you are seeing the message in console. If you use SMTP backend, then you can send this email to your acccount. For that, you need to configure like this:
First you need to update the backend in settings.py:
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
Then update the smtp configurations in settings.py:
# this configuration is for gmail
EMAIL_USE_TLS = True
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_HOST_USER = 'test#gmail.com'
EMAIL_HOST_PASSWORD = 'test'
EMAIL_PORT = 587
For details, please check the email documentation for Django.

Django crudbuilder & Bootstrap datepicker

Django==1.11.7
django-crudbuilder==0.2.5
Using Bootstrap datepicker. Now trying to use the datepicker in a crud form for a date field.
In a normal Django form, this would work:
self.fields['payment_date'].widget.attrs.update({'class': 'datepicker'})
But how can the class:datepicker be set for a particular field in a crud form?
The documentation doesn't seem to mention anything useful on css or html class.
Start with implementing custom templates.
Copy over the instance templates in crudbuilder/templates/crudbuilder/instance/ into your application template directory.
Replace the template location for the included form template in all the copied over instance templates .e.g. create.html
...
{% block main_content %}
<div class='container'>
<h3>Create {{actual_model_name|title}}</h3>
<hr/>
{% include "my_app/widgets/form.html" %}
</div>
{% endblock %}
In my_app/templates/my_app/widgets/form.html, write this instead to set the datepicker class on payment_date. (Original code was copied from django-cruid)
{% load crudbuilder %}
{% include "datepicker.html" %}
<form action="." method="post" enctype="multipart/form-data" class="form-horizontal" novalidate>
{% csrf_token %}
{% for field in form %}
<fieldset class={% if field.errors %} "form-group has-error" {% else %} "form-group" {% endif %} >
{{ field|label_with_class:"col-sm-2 control-label" }}
<div class="col-xs-4">
{% if field.name == 'payment_date' %}
{{ field|input_with_class:"form-control datepicker" }}
{% endif %}
{{ field|input_with_class:"form-control" }}
{{ field.errors }}
</div>
</fieldset>
{% endfor %}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-12">
<input type="submit" value="Save" class="btn btn-success" />
</div>
</div>
</form>
Finally, set your crud form to use your custom templates.
class PersonCrud(BaseCrudBuilder):
...
custom_templates = {
'list': 'my_app/list.html',
'create': 'my_app/create.html',
'detail': 'my_app/detail.html',
'update': 'my_app/update.html',
'delete': 'my_app/delete.html'
}

Resources