I've a strange problem with adding many-to-many relation in Flask app.Everything seems to be ok because when I use the code below in "Python Console" (PeCharm) I see a new relation in my database.
f = CAR.query.filter_by(ID_CAR=1).first()
m = MANAGER.query.filter_by(ID_MANAGER=1).first()
f.CAR_MENAGO.append(m)
db.session.commit()
but when I want to do it in Flask app using WTForms, nothing happen, I don't get any error even. Do You know what should I add to this code below ?
#app.route('/test1',methods=['GET', 'POST'])
#login_required
def test1():
form = test()
id_car = form.ID_CAR.data
f = CAR.query.filter_by(ID_CAR=id_car).first()
m = MANAGER.query.filter_by(ID_MANAGER=1).first()
if form.validate_on_submit():
f.CAR_MENAGO.append(m)
db.session.commit()
return render_template('test1.html',form=form)
return render_template('test1.html',form=form)
Template code:
{% extends "dashboardmanager.html" %}
{% import "bootstrap/wtf.html" as wtf %}
{% block content %}
<div class="container">
<form class="form-signin" method="post" action="/test1">
{{message}}
{{ form.hidden_tag() }}
{{ wtf.form_field(form.ID_CAR) }}
<button class="btn btn-success btn-xsy" type="submit">Submit</button>
</form>
</div>
{% endblock %}
Related
The code sample as novice of Django, is it right practice to achieve page load per ID as shown below?
View.py
def testidbasesearch(request,id=None):
if request.method == "GET":
print ('Inside IF GET')
if not id:
form = MtiForiegnForm()
else:
instance = Mt_Issue_foriegn.objects.get(id=id)
form = MtiForiegnForm(request.POST or None, instance=instance)
else:
print ('Inside Else GET')
id=request.POST.get('pkid')
return redirect(reverse('testidbasesearch', kwargs={"id": id}))
return render(request,'testingpost.html',{'form':form})
url.py
path('testidbasesearch',testidbasesearch,name='testidbasesearch'),
path('testidbasesearch/<int:id>',testidbasesearch,name='testidbasesearch'),
testingpost.html
{% extends 'base.html' %}
{% block content %}
<form id="postform1" method="post" action="">
{% csrf_token %}
<input type="text" name="pkid" />
<input type="submit" id="submit-form" />
{% for form1 in form %}
<fieldset disabled="disabled">
{{ form1 }}
</fieldset>
{% endfor %}
</form>
{% endblock %}
First of all my functionality is working as expected , I just need review is it right code practice, I purposely avoid AJAX/jquery ( i.e. js) pure django /python code to load form based on id submitted.
User login info is deleted when I delete posts.I wrote in views.py
def top(request):
if request.method == 'POST':
loginform = LoginForm(request, data=request.POST)
if loginform.is_valid():
user = loginform.get_user()
info = Info.objects.order_by('-created_at')
return render(request, 'top.html', {'info':info,'user': user})
loginform = LoginForm()
info = Info.objects.order_by('-created_at')
return render(request, 'top.html',{'info':info,'loginform':loginform,'user': request.user})
def delete(request):
delete_ids = request.POST.getlist('delete_ids')
if delete_ids:
Info.objects.filter(id__in=delete_ids).delete()
return redirect(reverse("app:top"))
in top.html
<div>
{% if user and not user.is_anonymous %}
<h2>{{ user.username }}</h2>
{% else %}
<form action="" method="POST">
<div>
{{ loginform.non_field_errors }}
{% for field in loginform %}
{{ field }}
{{ field.errors }}
{% endfor %}
</div>
<button type="submit">LOGIN</button>
{% csrf_token %}
</form>
{% endif %}
<div>
<form action="{% url 'app:delete' %}" method="POST">
{% csrf_token %}
{% for i in info %}
<input id="chkbox" type="checkbox" name="delete_ids" value="{{ i.pk }}" />
<div>
<p>{{ i.name }}</p>
</div>
{% endfor %}
<button type="submit">Delete</button>
</form>
Firstly I login to this app by putting LOGIN button,user.username is shown. And when I put Delete button to delete info,login info is deleted too(user.username is not shown).info is deleted but I really cannot understand why login info is deleted too.I cannot send user's info in redirect(reverse("app:top")),so shouldn't I use redirect?How should I fix this?
Looks like you forgot to login user. Try to add login() method:
from django.contrib.auth import login
def top(request):
if request.method == 'POST':
loginform = LoginForm(request, data=request.POST)
if loginform.is_valid():
user = loginform.get_user()
login(request, user)
Also it's better to use is_authenticated instead of is_anonymous:
{% if user.is_authenticated %}
I am learning Flask and trying build a very simple app which has few parts creating new users and searching the existing users. The create/register new users part is working just fine, but for some reason the search function is not working as expected because the form is not getting submitted. I have tried to look every possible case which I think of, searched Stackoverflow as well but could not get to fix it.
The code for registration functionality:
forms.py
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
from wtforms.validators import DataRequired, length
class Register(FlaskForm):
name = StringField('name', validators=[DataRequired(), length(min=1, max=30)])
email = StringField('email', validators=[DataRequired()])
submit = SubmitField('Register')
class UserSeacrh(FlaskForm):
name = StringField('name', validators=[DataRequired()])
email = StringField('email', validators=[DataRequired()])
submit = SubmitField('Search')
views.py
#app.route("/register", methods=['GET', 'POST'])
def register():
form = Register()
if form.validate_on_submit():
db.create_all()
user = CreateUser(form.name.data, form.email.data)
db.session.add(user)
db.session.commit()
flash('User {} created successfully'.format(form.name.data))
return redirect(url_for("register"))
return render_template("register.html", form=form, title='New User Registration')
#app.route("/search", methods=['GET', 'POST'])
def user_profile():
form = UserSeacrh()
if form.validate_on_submit():
flash('{}'.format(user))
return redirect(url_for("home"))
#return render_template("users.html", users=user)
return render_template("userSearch.html", form=form)
register.html
<!DOCTYPE html>
{% extends "base.html" %}
{% block body %}
<form action="" method="post">
{{ form.hidden_tag() }}
<div>
<h4>User Registeration</h4>
<span>Name {{form.name}}</span>
<span style="color: red">
{% for error in form.name.errors %}
{{error}}
{% endfor %}
</span
<span>Email {{form.email}}</span>
<span style="color: red">
{% for error in form.email.errors %}
{{error}}
{% endfor %}
</span>
</div>
{{form.submit()}}
</form>
{% with messages = get_flashed_messages() %}
{% if messages %}
<br/>
<ul>
{% for message in messages %}
<li>{{message}}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
{% endblock %}
userSearch.html
<!DOCTYPE html>
{% extends "base.html" %}
{% block body %}
<form action="" method="post">
{{ form.hidden_tag() }}
<h4>User Search Form</h4>
<div>
<span>Email {{form.email}}</span>
<span style="color: red">
{% for error in form.email.errors %}
{{error}}
{% endfor %}
</span>
</div>
{{form.submit()}}
</form>
{% with messages = get_flashed_messages() %}
{% if messages %}
<br/>
<ul>
{% for message in messages %}
<li>{{message}}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
{% endblock %}
I am clueless now, can someone please help me out here?
Most likely the reason is that in the userSearch.html you didn't add the name field. In the UserSeacrh class the field name has a validator DataRequired which most likely creates the problem. Just remove the name field in the UserSeacrh class if you want to do the search by email only.
By the way there is a typo in UserSeacrh - it should be UserSearch. But in your case it's not the problem.
I think you need to specify the action for your form, i.e., what URL to POST the completed form to.
<form action="" method="post">
I was able to solve this using Nurzhan' tip by removing the name field from UserSearch form from forms.py .
I'm using flask-bootstrap to use the Bootstrap front-end for a flask web application. Unfortunately, since I've started using flask-bootstrap and flask-nav, I'm not able to display flash messages.
This is the base.html:
{% extends 'bootstrap/base.html' %}
{% block navbar %}
{{ nav.mynavbar.render() }}
{% endblock %}
<html>
<body>
<hr>
<div class='container'>
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul class=flashes>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
</div>
{% endwith %}
{% block content %}{% endblock %}
</div>
</body>
</html>
This is one of the view that should flash a message when a change is saved:
#app.route('/model/<model_name>/edit', methods=['GET', 'POST'])
def edit(model_name):
"""Edit model's configuration.
Args:
model_name [str]: The name of the model we want to change the
configuration.
"""
# return to index page if model is not found in the database
model = DSModel.query.filter_by(name=model_name).first()
if not model:
flash('Model {} not found.'.format(model_name))
return redirect(url_for('index'))
# pre-load current model's configuration
form = ConfigurationForm()
# if it's a POST request, it means the user is trying to change the model's
# configuration. Save changes in the database
if request.method == 'POST': # and form.validate_on_submit():
model.configuration.configuration = form.value.data
model.configuration.datetime = datetime.datetime.utcnow()
db.session.add(model)
db.session.commit()
flash('Your changes have been saved.', 'success')
return redirect(url_for('edit', model_name=model_name))
else:
form.value.data = model.configuration.configuration
return render_template('edit.html', form=form)
Finally, this is the __init__.py:
from flask import Flask
from flask_bootstrap import Bootstrap
from flask_nav import Nav
from flask_nav.elements import Navbar, View
from flask_sqlalchemy import SQLAlchemy
nav = Nav()
#nav.navigation()
def mynavbar():
return Navbar(
'Dashboard',
View('Home', 'index'),
View('Login', 'login')
)
app = Flask(__name__)
Bootstrap(app)
nav.init_app(app)
app.config.from_object('config')
db = SQLAlchemy(app)
from app import views, models
I think there must be something funky with my base.html file, but I'm not terribly familiar with HTML, so I'm not able to find what's wrong. I've looked into examples online (i.e. here), but the format seems to be pretty similar to what I'm doing.
EDIT: This is the edit.html file:
{% extends 'base.html' %}
{% block content %}
<h1>Update configuration</h1>
<form action='' method='post' name='configuration'>
<p>
Please update the current model configuration:<br>
{{ form.value(cols='150', rows='20') }}
<p><input type='submit' value='Save'></p>
</form>
{% endblock %}
Try to edit your base.html to this:
{% extends 'bootstrap/base.html' %}
{% block navbar %}
{{ nav.mynavbar.render() }}
{% endblock %}
<html>
<body>
<hr>
<div class='container'>
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul class=flashes>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
</div>
{% block content %}{% endblock %}
</div>
</body>
</html>
I am having a form which takes some value as input, and I am processing the input and returning the required output. Now when I tried to display the output it not displaying on the webpage.
The following is my forms.py:
class CompForm(forms.ModelForm):
class Meta:
model = Comp
fields = ('inp',)
The following is my views.py:
def index(request):
form = CompForm(request.POST or None)
context = {
'form': form,
}
print context
if form.is_valid():
...
...
outData = "The values you gave is correct"
errData = "The values you gave is incorrect"
print context
context['outData'] = outData
context['errData'] = errData
print context
return render(request, 'comp/index.html', context)
The following is my index.html:
{% extends "comp/base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="row">
<div class="col-md-8 col-md-offset-2">
<form method="post" action="">
{% csrf_token %}
{{ form|crispy }}
<input class="btn btn-primary" type="submit" name="Submit" />
</form>
</div>
</div>
{% if outData %}
{{ outData.as_p }}
{% endif %}
{% if errData %}
{{ errData.as_p }}
{% endif %}
{% endblock %}
In the terminal I am able to get the outData and errData in the dictionary, but its not getting displayed in the webpage. What might be the mistake? Kindly help.
You are trying to called the method as_p on strings which doesn't make sense.
as_p() is a helper method on form instances to make it easier to render them in the template so you need:
{{ form.as_p }}
you can also use as_table and as_ul
You can read more in the documentation