How to get the latest ID from different class in Django - python

I saw all the conversations about this issue, but I can't solve it. I am new in this Python-Django programming so if anyone can help me? :)
This is my views.py:
class HistoryProjectCreate(CreateView):
template_name = 'layout/create_proj_history.html'
model = ProjectHistory
project = Project.objects.latest('id')
user = User.id
fields = ['user', 'project', 'user_start_date']
success_url = reverse_lazy('git_project:index')
Var project has to return latest project ID from database, and I have to use it ID in my html form:
<form class="form-horizontal" action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
<label for="user"></label>
<input id="user" type="text" name="user" value="{{ user.id }}" ><br>
<label for="project">Project title: </label>
<input id="project" type="text" name="project" value="{{ project.id }}" ><br>
<!--Here - "project.id" I need latest project ID-->
<label for="user_start_date">Start date: </label>
<input id="user_start_date" type="date" name="user_start_date" value="{{ projectHistory.user_start_date }}" ><br>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-success">Submit</button>
</div>
</div>
</form>
I am not sure if project = Project.objects.latest('id') is correct statement for getting the latest ID from Project table.

If you want the last Id of project, you need to order by id, and use last() function available on queryset
project = Project.objects.order_by('id').last()
Order_by doc
Last function doc

Related

Flask cannot see form

I'm trying to build a simple application using Leaflet in Flask, but I have a problem with the form. I want to send data from the form to my database but when I use the POST method, Flask doesn't want to read this method. When I used only GET, all values were empty in the database. When i used POST and GET nothing happened, none of the rows were added to the database.
forms.py
class EventForm(FlaskForm):
date_start = DateField(validators=[DataRequired()])
date_end = DateField(validators=[DataRequired()])
type = StringField(validators=[DataRequired()])
name = StringField(validators=[DataRequired()])
len_route = FloatField(validators=[DataRequired()])
mapa.html with Leaflet map and the form
<div id="fields">
<form action="" method="post">
<input type="text" id="route_len" class="form-control mb-2" name="route_len_input" placeholder="Długosc trasy">
<br>
<button id="draw-button" class="btn btn-success">Rysuj trase</button>
<br><br>
<input type="text" id="name" class="form-control mb-2" name="name_input" placeholder="Nazwa">
<br>
<input type="datetime-local" id="date_st" class="form-control mb-2" required name="date_st_input" placeholder="Data startu">
<br>
<input type="datetime-local" id="date_end" class="form-control mb-2" required name="date_end_input" placeholder="Data końcowa">
<br>
<select id="type" class="form-control mb-2" name="type_input">
<option></option>
<option value="Bieganie">Bieganie</option>
<option value="Rower">Rower</option>
<option value="Nordic walking">Nordic Walking</option>
</select>
<br>
<button type="submit" id="end-button" name="sub" class="btn btn-danger">Zakończ rysowanie</button>
<br><br>
</form>
</div>
routes.py
#app.route('/mapaa',methods=["GET","POST"])
def mapa():
if request.method == "POST":
data_pocz = request.form['date_st_input']
data_kon = request.form['date_end_input']
nazwa = request.form['name_input']
typ = request.form['type_input']
dlugosc = request.form['route_len_input']
event_database = Event(date_start=data_pocz, date_end=data_kon, type=typ, name=nazwa, len_route=dlugosc)
db.session.add(event_database)
db.session.commit()
return render_template('mapaa.html', title='Mapa')
You should link the form to your flask method
<form method="POST" action="/mapaa"> [...]

How to fill inputs when editing an article in flask

I have a list of articles.
After I press Edit, I am redirected to another page containing in the url the id of the article that wants to be edited.
Edit
This is where I am redirected:
And I want the inputs to be filled with the title and the body text of the respective article.
This is my backend function:
#app.route('/edit_article/<string:id>', methods=['POST', 'GET'])
def edit_article(id):
conn = mysql.connect()
cursor = conn.cursor()
result = cursor.execute("SELECT * from articles where id=%s", [id])
data = cursor.fetchone()
if result < 0:
flash("Article does not exist!")
cursor.close()
conn.close()
return render_template("edit_article.html", data=data)
How can I use data to fill those inputs? Please help. Thank you.
I will put also the edit_article.html
{% extends 'layout.html' %}
{% block body %}
<div class="container">
<div class="jumbotron">
<h1>Bucket List App</h1>
<form class="form-addArticle">
<label for="inputTitle" class="sr-only">Title</label>
<input type="name" name="inputTitle" id="inputTitle" class="form-control" placeholder="Title" required autofocus>
<label for="inputBody" class="sr-only">Body</label>
<input type="text" name="inputBody" id="inputBody" class="form-control" placeholder="Body" required autofocus>
<button id="btnEditArticle" class="btn btn-lg btn-primary" type="button">Update article</button>
</form>
<p class="text-center" style="color:red" id="message"></p>
</div>
</div>
{% endblock %}
You can just need to add value="{{ ... }}" to your inputs:
<input type="name" value="{{ data[0] }}" name="inputTitle" id="inputTitle" class="form-control" placeholder="Title" required autofocus>
<input type="text" value="{{ data[1] }}" name="inputBody" id="inputBody" class="form-control" placeholder="Body" required autofocus>
But it's recommended to name the values:
name, text = cursor.fetchone()
return render_template("edit_article.html", name=name, text=text)
and then
<input type="name" value="{{ name }}" name="inputTitle" id="inputTitle" class="form-control" placeholder="Title" required autofocus>
<input type="text" value="{{ text }}" name="inputBody" id="inputBody" class="form-control" placeholder="Body" required autofocus>
But I'd personally recommend WTForms module instead of rendering forms manually - it can for example help to validate your inputs properly.

django ModelForms and normal form in POST request

Hi i just have a small doubt can we create a HTML template which will have the Django form and normal HTML form together.
I created a HTML template which has both normal HTML input tag and Django forms.
I am getting the following error when i do a form.save(commit=False)
could not be created because the data didn't validate.
My view.py
if request.method == 'POST':
form_value = request.POST.copy()
print form_value
form = InfoForm(data=request.POST)
post_val = form.save(commit=False)
my HTML
<div class="form-row">
<div class="form-group col-md-4">
{{form.name}}
</div>
<div class="form-group col-md-4">
{{form.number}}
</div>
<div class="form-group col-md-4">
{{form.location}}
</div>
</div>
<div class="form-group">
<label for="Feedback">Feedback</label>
<div id="Feedback" class="optionBox1">
<div class="input-group my-add-div">
<input type="text" class="form-control" name="feedback" required>
<input type="text" class="form-control" name="feedback" required>
<input type="text" class="form-control" name="feedback" required>
</div>
</div>
</div>
my form.py
class InfoForm(forms.ModelForm):
name = forms.CharField(label='Project Name',max_length=100,widget=forms.TextInput(attrs={'class':'form-control','placeholder':'Click to enter text',}))
number = forms.DecimalField(label='Project #',widget=forms.NumberInput(attrs={'class':'form-control','placeholder':'Enter the ID',}))
location = forms.CharField(label='Location',max_length=100,widget=forms.TextInput(attrs={'class':'form-control','placeholder':'Enter the Location',}))
class Meta:
model = Info
field = ('name','number','location',)
My Model.py
name = models.CharField(max_length=200,blank=True , null=True)
number = models.IntegerField(blank=True , null=True)
location = models.CharField(max_length=200,blank=True , null=True)
feedback = ArrayField(ArrayField(models.CharField(max_length=200,blank=True,null=True)))
Thanks in advance
You need to first call form.is_valid() to use save method on the form.
All what you need to create any form in template you want, example:
``
<form action="." method="post">
{% csrf_token %}
<input type="text" name="first_name">
<p><input type='submit' value="Change"></p>
</form> ``
then, in your view call
first_name = request.POST['first_name']
and it will be works fine.

Bad Request with Flask

really struggling with this bad request from flask. I know normally it caused by flask not finding the [key] in the form.. However, I've checked my form and python code 40 times and cannot see any reason that would be the case.. I have commented out each line of the python code that references request.form. I have done it 1 by 1 and I still get a bad request. However when I comment out all the lines the bad request goes away.. Any thought would be wonderful..
Python code;
if request.method == 'POST':
form = 'Add Package Form'
clientId = request.form['id']
date = request.form['date2']
strPrice = request.form['price']
price = float(strPrice)
adultlessons = request.form['adult']
juniorlessons = request.form['junior']
shortlessons = request.form['short']
playinglessons = request.form['playing']
notes = request.form['notes']
form..
<form action="/addpackage" method="post" class="sky-form">
<fieldset>
<section>
<label class="label">Select Package Date</label>
<label class="input">
<i class="icon-append fa fa-calendar"></i>
<input type="text" name="date2" id="date">
</label>
</section>
<div style="margin: -25px"></div>
<fieldset>
<section>
<label class="label">Price</label>
<label class="input">
<input type="text" name="price">
</label>
</section>
<section>
<label class="label">Adult Lessons</label>
<label class="input">
<input type="text" name="adult">
</label>
</section>
<section>
<label class="label">Junior Lessons</label>
<label class="input">
<input type="text" name="junior">
</label>
</section>
<section>
<label class="label">Short Game Lessons</label>
<label class="input">
<input type="text" name="short">
</label>
</section>
<section>
<label class="label">Playing Lessons</label>
<label class="input">
<input type="text" name="playing">
</label>
</section>
<section>
<label class="label">Notes</label>
<label class="textarea textarea-expandable">
<textarea rows="3" name="notes"></textarea>
</label>
<div class="note"><strong>Note:</strong> expands on focus.</div>
</section>
</fieldset>
</fieldset>
<!-- hidden client id -->
<input type="hidden" name="id" value="{{ client.id }}">
<!-- /hidden client id -->
<footer>
<button type="submit" name="addpackage" value="package" class="button">Add Package</button>
</footer>
</form>
This is something of a half-answer, but it was too long for a comment.
If you enable debugging in your Flask app you should get a detailed traceback indicating exactly where the problem is occurring (both in the browser and on your console).
If your application currently has something like:
app.run()
Just set the debug parameter to true:
app.run(debug=True)
If after enabling debugging you're still not sure what's causing the problem, update your question to include the traceback.
For what it's worth, if I dump your form and your code into a simple Flask app, it all seems to work just fine as long as I provide a numeric value for the price field.
Usually you'll get a 400 Bad Request in Flask while submitting a form when you try and access a form key in the request object that doesn't exist.
This is because the request.form object inherits its __getitem__ method the Multidict class in the werkzeug.datastructures module which raises a BadRequestKeyError when a key doesn't exist.
You should give the form data a default value to avoid HTTP 400 error, like this:
default_value = True
is_public = request.form.get('public', default_value)
However, I recommend you to use Flask-WTF.
With Flask-WTF, your code can be simplify to this (an example):
import ...
app = Flask(__name__)
class EditProfileForm(Form):
name = StringField('name', validators=[Length(0, 64)])
location = StringField('city', validators=[Length(0,64)])
website = StringField('website', validators=[Length(0,64), render_kw={"placeholder": "http://..."})
about_me = TextAreaField('Bio', validators=[Length(0,2000)], render_kw={"placeholder": "I'm......"})
submit = SubmitField(u'submit')
#app.route('/edit-profile', methods=['GET', 'POST'])
def edit_profile():
form = EditProfileForm()
if form.validate_on_submit():
current_user.name = form.name.data
current_user.location = form.location.data
current_user.website = form.website.data
current_user.about_me = form.about_me.data
db.session.add(current_user)
flash('Update success!', 'success')
return redirect(url_for('.user', username=current_user.username))
return render_template('edit_profile.html', form=form)
In your html file:
<form method="POST" action="/">
{{ form.hidden_tag() }}
{{ form.name.label }} {{ form.name() }}
{{ form.location.label }} {{ form.location() }}
...
</form>
By the way, if you use Flask-Bootstrap, you can just use one line to render the whole form:
{% import "bootstrap/wtf.html" as wtf %}
{{ wtf.quick_form(form) }}
I hope it will help.

Django forms workaround

I'm a bit confused with all the django stuff and forms, I hope you can help me.
I'm migrating a cmd line app to django, and I think I don't need to mess with models (db) atm. I just would like to pass the parameters filled in a form to a python script that use these fields as parameters. I would like to keep my html code and skip render the form with a python form class since it has a lot of css code inside each one.
At the moment I have this form:
<form class="nobottommargin" id="template-contactform" name="template-contactform" action="{% url 'get_data' %}" method="post">
{% csrf_token %}
<div class="col_half">
<label for="name">Project Name <small>*</small></label>
<input type="text" id="name" name="name" value="{{ current_name }}" class="sm-form-control required" />
</div>
<div class="col_half col_last">
<label for="group">Project Group <small>*</small></label>
<input type="text" id="group" name="group" value="{{ current_group }}" class="required sm-form-control" />
</div>
<div class="clear"></div>
<div class="col_half">
<label for="version">Project Version<small>*</small></label>
<input type="text" id="version" name="version" value="{{ current_version }}" class="required sm-form-control" />
</div>
<div class="col_half col_last">
<label for="pType">Project Type<small>*</small></label>
<select id="pType" name="pType" class="required sm-form-control">
<option value="">-- Select One --</option>
<option value="bundle">Bundle</option>
<option value="multiple">Multiple</option>
<option value="git">Git</option>
</select>
</div>
<div class="col_half">
<label for="pPath">Project path<small>*</small></label>
<input type="text" id="pPath" name="pPath" value="{{ current_path }}" class="required sm-form-control" />
</div>
<div class="clear"></div>
<div class="col_full hidden">
<input type="text" id="template-contactform-botcheck" name="template-contactform-botcheck" value="" class="sm-form-control" />
</div>
<div class="col_full" style="margin: 50px 0 0 0 ">
<button class="button button-3d nomargin" type="submit" id="template-contactform-submit" name="template-contactform-submit" value="submit">Create Project</button>
</div>
</form>
So, I want to figure out what's the best way to write the get_data function. I also need some sort of custom validation about some fields that involves other checks that exceeds the basic checks, such as max_chars on each field. That means I need to create some sort of my own form.is_valid() function.
Hope you can help me!
Regards

Categories

Resources