Forms in Django

179 views
Skip to first unread message

Stanislav Vasko

unread,
Mar 18, 2016, 10:53:41 AM3/18/16
to Django users
Hello,

as a noob in Django, i will ask noob question about Forms, because i cant find.

I have working app, based on Bootstrap with theme and custom css. Rather than Django admin i want to create/edit data from my fields. I tried to use Django forms, but no luck. It looks... bad :) Its simple, but i have no controll over the result:

{% for field in form %}
    <div class="fieldWrapper">
        {{ field.errors }}
        {{ field.label_tag }} {{ field }}
        {% if field.help_text %}
        <p class="help">{{ field.help_text|safe }}</p>
        {% endif %}
    </div>
{% endfor %}

Insted of simple form i found form.as_p(), form.as_ul() aso, but it doesnt solve my problem too, just gives me little changed result. I need to be able insert and read data from my own tem plate, like: 

<div class="col-md-6 col-sm-6 col-xs-12 form-group has-feedback">
    <input class="form-control" id="inputSuccess5" placeholder="Phone" type="text">
    <span class="fa fa-phone form-control-feedback right" aria-hidden="true"></span>
</div>

Please, can you help me how to get clean data and after update put them back? Thanks for any tips or direct link.

Fred Stluka

unread,
Mar 18, 2016, 12:29:17 PM3/18/16
to django...@googlegroups.com
Stanislav,

Look at how you defined the fields of your Form class.

You probably defined the phone field as something like:

phone = forms.CharField(
    required   = True,
    max_length = 50,
    label      = u'Phone',
)

Change it to:

phone = forms.CharField(
    required   = True,
    max_length = 50,
    label      = u'',
    widget = forms.TextInput(
        attrs={
            'class'       : 'form-control',
            'id'          : 'inputSuccess5',
            'placeholder' : 'Phone',
        }
    ),
)

--Fred
Fred Stluka -- mailto:fr...@bristle.com -- http://bristle.com/~fred/
Bristle Software, Inc -- http://bristle.com -- Glad to be of service!
Open Source: Without walls and fences, we need no Windows or Gates.
--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/541fd731-d2b9-4fbd-807a-420ba5d21d3e%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Stanislav Vasko

unread,
Mar 18, 2016, 2:17:15 PM3/18/16
to Django users
Ufff, i hope there is another way. Something working so simple like passing data from View to Template with direct access like {{ company.name }} or {{ company.phone }}. I dont see the point why to modify Model and how it helps with styling form.

James Bennett

unread,
Mar 18, 2016, 2:23:25 PM3/18/16
to django...@googlegroups.com
First of all, notice the suggestion was to make the change on your *form* class, not the model -- forms are where you can specify that a particular widget + attributes should be used on a particular field.

Though it's also possible to do things in the template itself if you know your way around the forms API. I've used this handy little library a few times to do just that (since it knows its way around the forms API and lets you do quite a bit of rendering customization in the template):


On Fri, Mar 18, 2016 at 11:17 AM, Stanislav Vasko <stanisl...@gmail.com> wrote:
Ufff, i hope there is another way. Something working so simple like passing data from View to Template with direct access like {{ company.name }} or {{ company.phone }}. I dont see the point why to modify Model and how it helps with styling form.

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.

술욱

unread,
Mar 18, 2016, 2:31:16 PM3/18/16
to django...@googlegroups.com
2016-03-18 15:17 GMT-03:00 Stanislav Vasko <stanisl...@gmail.com>:
Ufff, i hope there is another way. Something working so simple like passing data from View to Template with direct access like {{ company.name }} or {{ company.phone }}. I dont see the point why to modify Model and how it helps with styling form.

You won't be modifying the model.  Just the form.

You need to tell Django to render the form using the css clases you want.

There are a few ways of doing that. One is Fred's way:

phone = forms.CharField(
    required   = True,
    max_length = 50,
    label      = u'',
    widget = forms.TextInput(
        attrs={
            'class'       : 'form-control',
   }
)

You can also do a custom template. So instead of letting Django render the form, you code the html yourself.

This is, instead of:

{{ form.as_p }}

do something like:

<form class="form" action="" method="post">{% csrf_token %}
<div class="col-md-6 col-sm-6 col-xs-12 form-group has-feedback">
    <input name="phone" class="form-control" id="id_phone" placeholder="Phone" type="text">
    <span class="fa fa-phone form-control-feedback right" aria-hidden="true"></span>
</div>
...
</form>


My favorite is to install django-crispy-forms, but may be overkill at the moment since you are just learning Django. If you are comfortable using modules/third-party apps, your template will be:

{% load crispy_forms_tags %}
{% crispy form %}


HTH,
Norberto

Stanislav Vasko

unread,
Mar 18, 2016, 2:55:10 PM3/18/16
to Django users
This is exactly what im trying. But if i enter {{ form.title }} i get not the data to use in form, but whole:

<input id="id_title" maxlength="200" name="title" value="Osobní schůzka, detailní probrání všech prací a podkladů z Topinfo" type="text">

But as i study doc, there is no simple way like Django is providing in other part. So, maybe Fred's way is a good one (but quite strange) and still dont know how i will make Fieldsets and other stuff (i need to work with data and some the result).

Maybe there is some better Django Form plugin, but i prefer not to use anything outside Django, because noone knows how it will work with new Django versions and how buggy it can be. As beginner i'm glad for solving own bugs not fighting others too :)

Fred Stluka

unread,
Mar 18, 2016, 3:50:37 PM3/18/16
to django...@googlegroups.com
Stanislav,

Try these:

{{ form.title.value }}
{{ form.title.label }}
{{ form.title.errors }}
etc.


--Fred
Fred Stluka -- mailto:fr...@bristle.com -- http://bristle.com/~fred/
Bristle Software, Inc -- http://bristle.com -- Glad to be of service!
Open Source: Without walls and fences, we need no Windows or Gates.
--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.

Stanislav Vasko

unread,
Mar 18, 2016, 3:54:35 PM3/18/16
to Django users
This is exactly what i was looking for, many thanks! Now i can render form i need and like. Now i will test and i hope it will be same easy to write data back to db.

Many thanks, Stanley

Dne pátek 18. března 2016 20:50:37 UTC+1 Fred Stluka napsal(a):
Stanislav,

Try these:

{{ form.title.value }}
{{ form.title.label }}
{{ form.title.errors }}
etc.

Fred Stluka

unread,
Mar 18, 2016, 9:43:31 PM3/18/16
to django...@googlegroups.com
Stanislav (aka Stanley?),

As my company motto says:  "Glad to be of service!".

I'm very impressed with Django.  It's a mature product that does
a good job of:
    "Making simple things easy, and complex things possible"
It has good simple default behaviors, but also hooks that you
can use to drill down to more detail when necessary.


For example, in my Django templates, I sometimes use:

{{form}}

but sometimes have to resort to:

{{ form.first_name }}
{{ form.last_name }}
{{ form.phone }}

and occasionally even:

{{ form.first_name.value }}
{{ form.first_name.label }}
{{ form.first_name.errors }}

{{ form.last_name.value }}
{{ form.last_name.label }}
{{ form.last_name.errors }}

{{ form.phone.value }}
{{ form.phone.label }}
{{ form.phone.errors }}


Similarly, in my Django ModelForms, I sometimes use:

class PersonModelForm(forms.ModelForm):
    class Meta:
        model=Person

but sometimes have to resort to:

class PersonModelForm(forms.ModelForm):
    class Meta:
        model=Person
        fields = ['first_name', 'last_name', 'phone',]

and occasionally even:

class PersonModelForm(forms.ModelForm):
    class Meta:
        model=Person
        exclude = ['middle_name',]

or take over a field explicitly as:


phone = forms.CharField(
    required   = True,
    max_length = 50,
    label      = u'',
    widget = forms.TextInput(
        attrs={
            'class'       : 'form-control',
            'id'          : 'my_custom_HTML_id',

            'placeholder' : 'Phone',
        }
    ),
)

or even give up on doing it all declaratively and do something
more dynamic in the __init__() of the Form, as:

def set_placeholders_from_labels(form):
    for field in form.fields.itervalues():
        field.widget.attrs['placeholder'] = field.label

class PersonForm(forms.Form):
    def __init__(self, *args, **kwargs):

        super(Donate2Form, self).__init__(*args, **kwargs)

        set_placeholders_from_labels(self)
        self.fields['amount'].widget.attrs['placeholder'] = ""

        if some_special_reason():
           
self.fields['amount'].initial = "100"

        keep_enabled = ['first_name','last_name'
]
        if some_mode_where_we_need_some_fields_disabled():
            for field in self.fields:
                if field not in keep_enabled:
                    self.fields[field].widget.attrs['disabled'] = True


And with validation of user-entered data, I can declare many
validation rules on the declarations of the fields, and can do
validation programmatically in the clean_field_name() methods
and the overall clean() method.  Or can even use the clean()
method of the Model instead of the clean() method of the form.


The ORM has similar hooks.  I can use it simply, to get() and
save() models from and to the DB.  Or can do fancier queries.
Or can drop down into raw SQL if necessary.


And I can use middleware to inject all sorts of useful functionality
into the HTTP request/response cycle, to change or add to the
default behavior, add caching of DB data, Django templates,
and fully assembled Django pages, etc.


And I can hook into Django "signals" for more sophisticated
needs.


Very powerful!

And I've found the community to be extraordinarily friendly and
helpful also.

Enjoy!
Bristle Software, Inc -- http://bristle.com -- Glad to be of service!
Open Source: Without walls and fences, we need no Windows or Gates.

Stanislav Vasko

unread,
Mar 19, 2016, 8:08:23 AM3/19/16
to Django users
Outstanding answer, many thanks! This is exactly what i thought there must be :)

Dne sobota 19. března 2016 2:43:31 UTC+1 Fred Stluka napsal(a):
--Fred

Fred Stluka

unread,
Mar 20, 2016, 8:10:31 PM3/20/16
to django...@googlegroups.com
Stanislav,

If you have any more questions, feel free to post them here.

BTW, one thing I forgot to mention about the flexibility of
the ORM is that you can have it access multiple databases
from the same app, by setting DATABASE_ROUTERS to refer
to a class that tells it things like which DB to use for reading
and for writing each model.

Also, I've had very good luck using the ORM to migrate from
one DB server to another.  For example, on my current project
we're re-writing an old ColdFusion app that used an old
Microsoft SQL Server DB as a new Django app that uses MySQL.

With a one-line command, we were able to create Django
models from all of the MS SQL Server tables:
% manage.py inspectdb

Then with another one-line command, we were able to create
MySQL tables from the models:
% manage.py syncdb

Never had to look at the different DDL of MS SQL Server vs
MySQL, or the native tools of each to export and import DDL.

Since then, we've kept our DEV, TEST, and PROD instances of
the MySQL DB up to date via Django "migrations".

And when we accumulated enough automated regression tests
that it took too long to run the test suite, we changed the
DATABASES setting to use SQLite instead of MySQL when
running tests, by simply adding:
RUNNING_UNIT_TESTS = 'test' in sys.argv
if RUNNING_UNIT_TESTS:
    DATABASES['default'] = {
        'ENGINE': 'django.db.backends.sqlite3',

Again, we never had to look at the different DDL of MySQL vs SQLite, or the native tools of each to export and import DDL. Django did it all for us. Suddenly the entire regression test suite runs in 30 seconds instead of 75 minutes. Really nice!
--Fred
Fred Stluka -- mailto:fr...@bristle.com -- http://bristle.com/~fred/ Bristle Software, Inc -- http://bristle.com -- Glad to be of service! Open Source: Without walls and fences, we need no Windows or Gates.
-- You received this message because you are subscribed to the Google Groups "Django users" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com. To post to this group, send email to django...@googlegroups.com. Visit this group at https://groups.google.com/group/django-users. To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/8774a303-b754-4125-9f1e-bf30ccf99a9c%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages