I am now studying Django form
. Right now I am focusing on crispy form
.
For now crispy and then after I master the form
I will move on to Django Admin form
and Django admin model form
.
Django 1.10
Python 3.6.0
I am following these tutorials:
https://blog.bixly.com/awesome-forms-django-crispy-forms
http://django-crispy-forms.readthedocs.io/en/latest/layouts.html#
https://godjango.com/29-crispy-forms/
Here are my source code:
views.py:
from django.views.generic import FormView
from apps.colors.forms import PersonDetailForm
class ColorStudyView(FormView):
template_name = 'colors/study.html'
form_class = PersonDetailForm
success_url = '/'
forms.py:
from crispy_forms.bootstrap import Tab, TabHolder
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit, Layout
from django import forms
class NoFormTagCrispyFormMixin(object):
@property
def helper(self):
if not hasattr(self, '_helper'):
self._helper = FormHelper()
self._helper.form_tag = False
return self._helper
class PersonDetailForm(forms.Form):
name = forms.CharField(max_length=100)
age = forms.IntegerField(required=False)
address1 = forms.CharField(max_length=50, required=False)
address2 = forms.CharField(max_length=50, required=False)
city = forms.CharField(max_length=50, required=False)
state = forms.CharField(max_length=50, required=False)
mobile = forms.CharField(max_length=32, required=False)
home = forms.CharField(max_length=32, required=False)
office = forms.CharField(max_length=32, required=False)
twitter = forms.CharField(max_length=100, required=False)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_tag = False
self.helper.layout = Layout(
TabHolder(
Tab('Information',
'name',
'age'
),
Tab('Address',
'address1',
'address2',
'city',
'state'
),
Tab('Contact',
'mobile',
'home',
'office',
'twitter',
)
)
)
self.helper.layout.append(Submit('submit', 'Submit'))
study.html:
{% load crispy_forms_tags %}
<!DOCTYPE html>
<html lang="en">
<head>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet" />
<meta charset="UTF-8">
<title>Study</title>
<form action="" method="POST">
{% crispy form %}
</form>
</head>
<body>
</body>
</html>
Problem:
Tab does not change.
Am I miss something?
Sorry for very basic level question, but this is my first day with Django frontend
Here is my picture. Tab Address
and Contact
are not work.
Update: Zollie solves my problem. Here is my study.html
{% load staticfiles %}
{% load crispy_forms_tags %}
<!DOCTYPE html>
<html lang="en">
<head>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet" />
<meta charset="UTF-8">
<title>Study</title>
<form action="" method="POST">
{% crispy form %}
</form>
</head>
<body>
<script src="http://code.jquery.com/jquery-1.9.1.js">
</script>
<script src="http://code.jquery.com/ui/1.11.0/jquery-ui.js">
</script>
<script type="text/javascript" src="{% static 'bootstrap-tab.js' %}"> </script>
</body>
</html>
And here is my filesystem configuration
/Users/el/Code/siam-sbrand/static
(siam-sbrand) Sarits-MacBook-Air-2:static el$ ls
admin django_extensions img
bootstrap-tab.js file.txt js
dist font rest_framework
I had the same problem when first I wanted to use the Tabs in crispy forms. The documentation is quite weak unfortunately for this package.
The answer on why TabHolder and Tabs are not working is, because you have to include jquery and javascript in your html template head. Also, you have to download bootstrap-tab.js and put it in your 'static' folder in the bootstrap subfolder ie., and you also have to include the path to it in your html .
So, it is not enough if you just include Bootstrap or bootstrap.css in the html head. Here is an example how it should look like:
<head>
<script src="http://code.jquery.com/jquery-1.9.1.js">
</script>
<script src="http://code.jquery.com/ui/1.11.0/jquery-ui.js">
</script>
<script type="text/javascript" src="{% static 'bootstrap/js/bootstrap-tab.js' %}"> </script>
Check these things:
CRISPY_TEMPLATE_PACK = 'bootstrap3'
Although the question is old and solved, I find it might be worthwhile to add some more observations: I came across the problem and found another cause.
First, I checked and confirmed that I had included the .js files as mentioned in the accepted answer. But the tab still did not work.
I found some bootstrap tab examples, such as https://mdbootstrap.com/docs/jquery/components/tabs/ . And I concluded that, to make tab work, one should make sure there is a one-to-one relationship between the href attr of the 'tab header' and the id attr of the 'tab body'. Like this:
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="home-tab" data-toggle="tab" href="#home" role="tab" aria-controls="home"
aria-selected="true">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" id="profile-tab" data-toggle="tab" href="#profile" role="tab" aria-controls="profile"
aria-selected="false">Profile</a>
</li>
<li class="nav-item">
<a class="nav-link" id="contact-tab" data-toggle="tab" href="#contact" role="tab" aria-controls="contact"
aria-selected="false">Contact</a>
</li>
</ul>
<div class="tab-content" id="myTabContent">
<div class="tab-pane fade show active" id="home" role="tabpanel" aria-labelledby="home-tab">A Tab</div>
<div class="tab-pane fade" id="profile" role="tabpanel" aria-labelledby="profile-tab">B tab</div>
<div class="tab-pane fade" id="contact" role="tabpanel" aria-labelledby="contact-tab">C tab</div>
</div>
Note: pay attention to the href attrs of 'a' elements and the id attrs of 'div' elements.
I did some experimentation and concluded that: once related .js and other files are imported and href and id attrs are properly set, the tab would work.
Now the problem became "how to make crispy set them properly".
I checked following files: 1. /root/.pyenv/versions/3.7.3/lib/python3.7/site-packages/crispy_forms/bootstrap.py
class Tab(Container):
"""
Tab object. It wraps fields in a div whose default class is "tab-pane" and
takes a name as first argument. Example::
Tab('tab_name', 'form_field_1', 'form_field_2', 'form_field_3')
"""
css_class = 'tab-pane'
link_template = '%s/layout/tab-link.html'
def render_link(self, template_pack=TEMPLATE_PACK, **kwargs):
"""
Render the link for the tab-pane. It must be called after render so css_class is updated
with active if needed.
"""
link_template = self.link_template % template_pack
return render_to_string(link_template, {'link': self})
<li class="tab-pane{% if 'active' in link.css_class %} active{% endif %}"><a href="#{{ link.css_id }}" data-toggle="tab">{{ link.name|capfirst }}{% if tab.errors %}!{% endif %}</a></li>
I noticed the css_id attr. And I guessed that if one set 'css_id' properly, maybe crispy would do the rest. I tried. And it worked like a charm.
Maybe crispy documentation needs some improvement.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.