I would like to use date picker in my template. Is there a way to omit stuff in forms.py and simply do something like:
<tr class="new">
<form method="post">
{% csrf_token %}
<td>
<input size="10" type="text" class="form-control" id="date" name="{{ form.date }}">
<script type="text/javascript">
$("#date").datepicker({format: "dd/mm/yyyy", autoclose: true});
</script>
</td>
...
That is, to use the {{ form.date }} as a name in input for example? Unfortunately this solution doesn't work for me.
You can define custom input fields with HTML or Bootstrap, as long as you let Django know, which input field in your forms.py you mean. You do this by specifying the proper id to the HTML input field.
For example, if you have a form which takes a DateField in your forms.py:
from django import forms
class YourForm(forms.Form):
some_date = forms.DateField()
# ... more stuff
Then, your proper id for the input would be id='id_some_date'.
(And name would be name='some_date'.)
EDIT: In your case, you can try id='{{ form.date.id_for_label }}', so you do not need to hardcode the id.
When the template is rendered, {{ form.date }} would render to the HTML input form, which is the form you specified in forms.py.
Related
I have a FieldList form that allows users to enter in an origin and destination for routes they have travelled.
I am trying to add Google's autocomplete API to make it easier for users to enter in addresses into the fields.
forms.py
from flask_wtf import Form
from wtforms import (
StringField,
FormField,
FieldList
)
from wtforms.validators import (
Length,
Optional
)
class RouteForm(Form):
origin = StringField([Optional(), Length(1, 256)])
destination = StringField([Optional(), Length(1, 256)])
class JourneysForm(Form):
ids = []
journeys = FieldList(FormField(RouteForm))
edit.html
{% import 'macros/form.html' as f with context %}
<tbody>
<tr>
{% for journey, route in zip(form.journeys, routes) %}
<td>
{% call f.location_search(journey.origin,
css_class='sm-margin-bottom hide-label') %}
{% endcall %}
</td>
</tr>
{% endfor %}
</tbody>
<div class="col-md-6">
<button type="submit" class="btn btn-primary btn-block">
'Save'
</button>
</div>
macros/forms.html
<head>
<script src="https://maps.googleapis.com/maps/api/js?libraries=places&key=<KEY>&callback=initMap" async defer></script>
<script>
function initMap() {
var input = document.getElementById('searchInput');
var autocomplete = new google.maps.places.Autocomplete(input);
}
</script>
</head>
{# Render a form for searching a location. #}
{%- macro location_search(form, css_class='') -%}
<input type="text" class="form-control"
id="searchInput" placeholder="Enter location">
{{ form(class=css_class, **kwargs) }}
{{ caller () }}
{%- endmacro -%}
routes.py
#route('/edit', methods=['GET', 'POST'])
def routes_edit():
routes = get_routes()
journeys_form = JourneysForm()
if journeys_form.validate_on_submit():
for i, entry in enumerate(journeys_form.journeys.entries):
origin = entry.data['origin']
However, this renders two fields. One which contains the Google autocomplete input, but does not submit the value (top). And another field which does not have the Google autocomplete input but submits the value to the db via routes.py (bottom).
Is it possible to combine this into a single field that both contains the Google autocomplete and submits the input value to the db?
WTForms actually renders an input class itself:
<input class="form-control" id="journeys-0-origin" name="journeys-0-origin" type="text" value="" placeholder="Enter a location" autocomplete="off">
Therefore I was unnecessarily duplicating the input element. In order to get Google autocomplete to work I simply just had to pass the input id into my js function:
function initMap() {
var input = document.getElementById('journeys-0-origin');
var autocomplete = new google.maps.places.Autocomplete(input);
}
I have a generic view and a form template.
my view is:
class BlogCreateView(CreateView):
model = Post
template_name = "post_new.html"
fields = "__all__"
and my form template is:
{% extends "base.html" %}
{% block content %}
<h1>New Post</h1>
<form action="" method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Save" />
</form>
{% endblock content %}
now my question is about form.as_p or specifically form.
Where did that come from?
help me please. thanks a lot
.as_p() [Django-doc] is a method on a Form. It produces a SafeText object [Django-doc] that contains HTML code to be included in the template.
The fact that it is SafeText is important, since the Django render engine will otherwise "escape" it: without using SafeText, it would replace < with <; > with >, etc. Unless of course you wrap it in a SafeText object yourself, for example through the |safe template filter [Django-doc].
We can for example define a form like in the documentation:
class OptionalPersonForm(forms.Form):
first_name = forms.CharField()
last_name = forms.CharField()
nick_name = forms.CharField(required=False)
If we then construct a form object, we can call the .as_p() method:
>>> OptionalPersonForm().as_p()
'<p><label for="id_first_name">First name:</label> <input type="text" name="first_name" required id="id_first_name"></p>\n<p><label for="id_last_name">Last name:</label> <input type="text" name="last_name" required id="id_last_name"></p>\n<p><label for="id_nick_name">Nick name:</label> <input type="text" name="nick_name" id="id_nick_name"></p>'
>>> type(OptionalPersonForm().as_p())
<class 'django.utils.safestring.SafeText'>
Django forms have three popular rendering methods: .as_p, .as_table() [Django-doc] and .as_ul() [Django-doc]. The difference is that these render the HTML slightly differently: as paragraphs, a table or unordered HTML list.
New to Django.
I am trying to build a blog of my own, so I will need to input an article with max_length = 5000 or some other number; I don't want to use the admin system directly, instead I want to input the article and submit it to the server.Right now I am trying to use forms.
The question is I didn't find a solution to this huge amount of character inputs.
Any hint to this?
The form:
<form name="input" method="POST">
<li>The title:{{ form.name }}</li>
<li>The body: <textarea cols='20' rows='20'>{{ form.text }}</textarea> </li>
<input type="submit" value="Submit">
</form>
UPDATE:
I solved this issue by deleting the textarea tag wrapping {{ form.text }};
{{ form.text }} itself implements a textarea tag.
And in my view code:
text = forms.CharField(widget=forms.Textarea)
I'm having trouble wiring my checkboxes together with the template to make a good user experience. I'm sending my form to the view which contains the following MyType which is described as:
models
class A(models.Model):
MyType = models.ManyToManyField(P)
forms
MyType = forms.ModelMultipleChoiceField(queryset=P.objects.all(), required=False, widget=forms.CheckboxSelectMultiple)
and the view is being sent as:
return render(request, "static/about.html", {'form': form})
and in the template, I have the following kind of structure
<li class="option table">
<div class="cell" id="center">
<div class="option-text">Option 1</div>
</div>
<div class="cell" id="right">
<div class="option-checkbox">
<div class="check"></div>
<input id="myid1" name="myname1" value="1" type="checkbox">
</div>
</div>
Now I can use answer: On a django form, how do I loop through individual options per field? to loop through, but this only gives the description. How do I recreate the actual HTML that deals with the options in the smartest way?
I've tried the shell to look at the objects, but I really don't see what I should be pulling in. i.e. in the template to recreate. What fields of each option should I pull in? or how do I get at the right info to build up my HTML such that the saving aspect of the form will work.
In a template I cannot do:
{% for field in form["MySmoking"] %}
{% endfor %}
so how could I modify the following:
{% for option in form.MyType.field.choices.queryset %}
{{ option.image }}
{{ option.title }}
{{ option.description }}
{% endfor %}
so, how would I spit out the HTML that builds the checkbox.
Thanks.
How to set the html form fields without using django-forms.
If you do not wish to use django.forms, but get data from a model and display it into a html form, you could do something like this:
views.py
from django.shortcuts import render_to_response, redirect
from myApp.models import MyModel
def editForm(request, model_pk):
model = MyModel.objects.get(pk=model_pk)
return render_to_response('formUpdate.html',{ 'model' : model })
def updateForm(request, model_pk):
model = MyModel.objects.get(pk=model_pk)
model.firstname = request.POST['firstname']
model.lastname = request.POST['lastname']
model.save()
return redirect('home', message='your name has been updated')
template - formUpdate.html
{% extends "base.html" %}
{% block content %}
<form action="/updateForm/{{ model.id }}/" method="post">
First name: <input type="text" name="firstname" value="{{ model.firstname }}" /><br />
Last name: <input type="text" name="lastname" value="{{ model.lastname }}" /><br />
<input type="submit" value="submit" />
</form>
{% end block %}
models.py
from django.db import models
class MyModel(models.Model):
firstname = models.CharField(max_length=20)
lastname = models.CharField(max_length=20)
urls.py
from django.conf.urls.defaults import *
urlpatterns = patterns('',
(r'^$', 'views.home', name="home"),
(r'^editForm/(?P<model_pk>\d+)/$', 'views.editForm'),
(r'^updateForm/(?P<model_pk>\d+)/$', 'views.updateForm'),
)
This is very similar to how forms are processed in PHP or similar, the model is passed into the template where the existing values are rendered. The id or pk (primary key) of the model is passed to the view via the URL and then updated values then returned to the storing view in the POST data where they can be retrieved and the updated values stored in the database.
One of the beauties of Django is how it balances speed of development with plugability - pretty much any of it's parts can be replaced or altered.
Having said this, is there a reason why you don't want to use django.forms? To my understanding a form simply performs most of the hard work in the example above for you, this is what django.forms are for. They also have other features, to help prevent malicious access of your web app, for example, OOTB. It is fairly easy to create ajax helper methods to retrieve and update them also.
You can do that as you would create a normal form in html. Just be careful to place the {% csrf_token %}. And the name of the input in the form, as they will be used in the view.
Eg:
<form method="post" action="#the url for the view">
{% csrf_token %}
...
...
<!-- fields that you want Eg: -->
<label for="username">User name:</label>
<input type="text" name="username" id="username" />
...
...
<input type="submit" value="Submit" />
</form>
Hope this helped.