Hello community,

here is the log from the commit of package python-django-crispy-forms for 
openSUSE:Factory checked in at 2019-10-30 14:49:04
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-django-crispy-forms (Old)
 and      /work/SRC/openSUSE:Factory/.python-django-crispy-forms.new.2990 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-django-crispy-forms"

Wed Oct 30 14:49:04 2019 rev:5 rq:744151 version:1.8.0

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-django-crispy-forms/python-django-crispy-forms.changes
    2019-09-17 13:39:15.169825221 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-django-crispy-forms.new.2990/python-django-crispy-forms.changes
  2019-10-30 14:49:05.630263633 +0100
@@ -1,0 +2,10 @@
+Wed Oct 30 12:08:12 UTC 2019 - Tomáš Chvátal <[email protected]>
+
+- Update to 1.8.0:
+  * Update to support new django releases
+  * Numerous improvements to bootstrap4 template pack
+- Remove patches:
+  * django-21.patch
+  * django-20.patch
+
+-------------------------------------------------------------------

Old:
----
  django-20.patch
  django-21.patch
  django-crispy-forms-1.7.2.tar.gz

New:
----
  django-crispy-forms-1.8.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-django-crispy-forms.spec ++++++
--- /var/tmp/diff_new_pack.BEa0h9/_old  2019-10-30 14:49:06.666264735 +0100
+++ /var/tmp/diff_new_pack.BEa0h9/_new  2019-10-30 14:49:06.678264747 +0100
@@ -19,18 +19,16 @@
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 %define mod_name django-crispy-forms
 Name:           python-%{mod_name}
-Version:        1.7.2
+Version:        1.8.0
 Release:        0
 Summary:        Django DRY Forms
 License:        MIT
 Group:          Development/Languages/Python
 URL:            http://github.com/maraujop/django-crispy-forms
 Source:         
https://files.pythonhosted.org/packages/source/d/%{mod_name}/%{mod_name}-%{version}.tar.gz
-Patch0:         django-20.patch
-Patch1:         django-21.patch
 BuildRequires:  %{python_module Django}
-BuildRequires:  %{python_module pytest < 4.0}
 BuildRequires:  %{python_module pytest-django}
+BuildRequires:  %{python_module pytest}
 BuildRequires:  %{python_module setuptools}
 BuildRequires:  fdupes
 BuildRequires:  python-rpm-macros
@@ -46,16 +44,13 @@
 
 %prep
 %setup -q -n %{mod_name}-%{version}
-%autopatch -p1
-
-# Remove not needed files
-find . -name '*.pyc' -delete
 
 %build
 %python_build
 
 %check
-%python_expand PYTHONPATH=`pwd` 
DJANGO_SETTINGS_MODULE=crispy_forms.tests.test_settings 
py.test-%{$python_version} crispy_forms/tests
+export DJANGO_SETTINGS_MODULE=crispy_forms.tests.test_settings
+%pytest
 
 %install
 %python_install

++++++ django-crispy-forms-1.7.2.tar.gz -> django-crispy-forms-1.8.0.tar.gz 
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-crispy-forms-1.7.2/PKG-INFO 
new/django-crispy-forms-1.8.0/PKG-INFO
--- old/django-crispy-forms-1.7.2/PKG-INFO      2018-03-09 15:47:00.000000000 
+0100
+++ new/django-crispy-forms-1.8.0/PKG-INFO      2019-10-17 17:25:16.000000000 
+0200
@@ -1,12 +1,11 @@
 Metadata-Version: 1.1
 Name: django-crispy-forms
-Version: 1.7.2
+Version: 1.8.0
 Summary: Best way to have Django DRY forms
-Home-page: http://github.com/maraujop/django-crispy-forms
+Home-page: http://github.com/djang-crispy-forms/django-crispy-forms
 Author: Miguel Araujo
 Author-email: [email protected]
 License: MIT
-Description-Content-Type: UNKNOWN
 Description: ===================
         django-crispy-forms
         ===================
@@ -20,17 +19,17 @@
         
         The best way to have Django_ DRY forms. Build programmatic reusable 
layouts out of components, having full control of the rendered HTML without 
writing HTML in templates. All this without breaking the standard way of doing 
things in Django, so it plays nice with any other form application.
         
-        `django-crispy-forms` supports Python 2.7/Python 3.3+ and Django 
1.8/Django 1.10+
+        `django-crispy-forms` supports Python 2.7/Python 3.5+ and Django 1.11, 
2.1, 2.2 and 3.0.
         
         The application mainly provides:
         
         * A filter named ``|crispy`` that will render elegant div based forms. 
Think of it as the built-in methods: ``as_table``, ``as_ul`` and ``as_p``. You 
cannot tune up the output, but it is easy to start using it.
         * A tag named ``{% crispy %}`` that will render a form based on your 
configuration and specific layout setup. This gives you amazing power without 
much hassle, helping you save tons of time.
         
-        Django-crispy-forms supports several frontend frameworks, such as 
Twitter `Bootstrap`_ (versions 2 and 3), `Uni-form`_ and Foundation. You can 
also easily adapt your custom company's one, creating your own, `see the docs`_ 
for more information. You can easily switch among them using 
``CRISPY_TEMPLATE_PACK`` setting variable.
+        Django-crispy-forms supports several frontend frameworks, such as 
Twitter `Bootstrap`_ (versions 2, 3, and 4), `Uni-form`_ and Foundation. You 
can also easily adapt your custom company's one, creating your own, `see the 
docs`_ for more information. You can easily switch among them using 
``CRISPY_TEMPLATE_PACK`` setting variable.
         
         .. _`Uni-form`: http://sprawsm.com/uni-form
-        .. _`Bootstrap`: http://twitter.github.com/bootstrap/index.html
+        .. _`Bootstrap`: https://getbootstrap.com
         .. _`see the docs`: https://django-crispy-forms.readthedocs.io
         
         Authors
@@ -81,14 +80,19 @@
 Classifier: Development Status :: 5 - Production/Stable
 Classifier: Environment :: Web Environment
 Classifier: Framework :: Django
+Classifier: Framework :: Django :: 1.11
+Classifier: Framework :: Django :: 2.1
+Classifier: Framework :: Django :: 2.2
 Classifier: License :: OSI Approved :: MIT License
 Classifier: Operating System :: OS Independent
 Classifier: Programming Language :: JavaScript
+Classifier: Programming Language :: Python :: 2
 Classifier: Programming Language :: Python :: 2.7
-Classifier: Programming Language :: Python :: 3.3
-Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3
 Classifier: Programming Language :: Python :: 3.5
 Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
 Classifier: Topic :: Internet :: WWW/HTTP
 Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
 Classifier: Topic :: Software Development :: Libraries :: Python Modules
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-crispy-forms-1.7.2/README.rst 
new/django-crispy-forms-1.8.0/README.rst
--- old/django-crispy-forms-1.7.2/README.rst    2017-10-17 16:10:19.000000000 
+0200
+++ new/django-crispy-forms-1.8.0/README.rst    2019-10-17 17:14:45.000000000 
+0200
@@ -11,17 +11,17 @@
 
 The best way to have Django_ DRY forms. Build programmatic reusable layouts 
out of components, having full control of the rendered HTML without writing 
HTML in templates. All this without breaking the standard way of doing things 
in Django, so it plays nice with any other form application.
 
-`django-crispy-forms` supports Python 2.7/Python 3.3+ and Django 1.8/Django 
1.10+
+`django-crispy-forms` supports Python 2.7/Python 3.5+ and Django 1.11, 2.1, 
2.2 and 3.0.
 
 The application mainly provides:
 
 * A filter named ``|crispy`` that will render elegant div based forms. Think 
of it as the built-in methods: ``as_table``, ``as_ul`` and ``as_p``. You cannot 
tune up the output, but it is easy to start using it.
 * A tag named ``{% crispy %}`` that will render a form based on your 
configuration and specific layout setup. This gives you amazing power without 
much hassle, helping you save tons of time.
 
-Django-crispy-forms supports several frontend frameworks, such as Twitter 
`Bootstrap`_ (versions 2 and 3), `Uni-form`_ and Foundation. You can also 
easily adapt your custom company's one, creating your own, `see the docs`_ for 
more information. You can easily switch among them using 
``CRISPY_TEMPLATE_PACK`` setting variable.
+Django-crispy-forms supports several frontend frameworks, such as Twitter 
`Bootstrap`_ (versions 2, 3, and 4), `Uni-form`_ and Foundation. You can also 
easily adapt your custom company's one, creating your own, `see the docs`_ for 
more information. You can easily switch among them using 
``CRISPY_TEMPLATE_PACK`` setting variable.
 
 .. _`Uni-form`: http://sprawsm.com/uni-form
-.. _`Bootstrap`: http://twitter.github.com/bootstrap/index.html
+.. _`Bootstrap`: https://getbootstrap.com
 .. _`see the docs`: https://django-crispy-forms.readthedocs.io
 
 Authors
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-crispy-forms-1.7.2/crispy_forms/__init__.py 
new/django-crispy-forms-1.8.0/crispy_forms/__init__.py
--- old/django-crispy-forms-1.7.2/crispy_forms/__init__.py      2018-03-09 
15:42:59.000000000 +0100
+++ new/django-crispy-forms-1.8.0/crispy_forms/__init__.py      2019-10-17 
17:14:45.000000000 +0200
@@ -1,3 +1,3 @@
 # -*- coding: utf-8 -*-
 
-__version__ = '1.7.2'
+__version__ = '1.8.0'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-crispy-forms-1.7.2/crispy_forms/compatibility.py 
new/django-crispy-forms-1.8.0/crispy_forms/compatibility.py
--- old/django-crispy-forms-1.7.2/crispy_forms/compatibility.py 2017-10-17 
16:10:19.000000000 +0200
+++ new/django-crispy-forms-1.8.0/crispy_forms/compatibility.py 2019-10-10 
06:46:48.000000000 +0200
@@ -1,4 +1,5 @@
 import sys
+import django
 
 try:
     basestring
@@ -16,3 +17,8 @@
     binary_type = str
     string_types = basestring
     integer_types = (int, long)
+
+if django.VERSION < (3, 0):
+    from django.utils.lru_cache import lru_cache
+else:
+    from functools import lru_cache
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-crispy-forms-1.7.2/crispy_forms/helper.py 
new/django-crispy-forms-1.8.0/crispy_forms/helper.py
--- old/django-crispy-forms-1.7.2/crispy_forms/helper.py        2018-03-05 
15:49:56.000000000 +0100
+++ new/django-crispy-forms-1.8.0/crispy_forms/helper.py        2019-10-17 
17:14:45.000000000 +0200
@@ -125,7 +125,7 @@
     Let's see what attributes you can set and what form behaviors they apply 
to:
 
         **form_method**: Specifies form method attribute.
-            You can see it to 'POST' or 'GET'. Defaults to 'POST'
+            You can set it to 'POST' or 'GET'. Defaults to 'POST'
 
         **form_action**: Applied to the form action attribute:
             - Can be a named url in your URLconf that can be executed via the 
`{% url %}` template tag. \
@@ -215,6 +215,7 @@
     template = None
     field_template = None
     disable_csrf = False
+    use_custom_control = True
     label_class = ''
     field_class = ''
     include_media = True
@@ -364,17 +365,28 @@
             'html5_required': self.html5_required,
             'form_show_labels': self.form_show_labels,
             'disable_csrf': self.disable_csrf,
+            'use_custom_control': self.use_custom_control,
             'label_class': self.label_class,
             'field_class': self.field_class,
             'include_media': self.include_media
         }
-        bootstrap_size_match = re.findall('col-(lg|md|sm|xs)-(\d+)', 
self.label_class)
-        if bootstrap_size_match:
-            if template_pack == 'bootstrap4':
-                offset_pattern = 'offset-%s-%s'
-            else:
-                offset_pattern = 'col-%s-offset-%s'
-            items['bootstrap_checkbox_offsets'] = [offset_pattern % m for m in 
bootstrap_size_match]
+        
+        if template_pack == 'bootstrap4':
+            bootstrap_size_match = re.findall(r'col-(xl|lg|md|sm)-(\d+)', 
self.label_class)
+            if bootstrap_size_match:
+                if template_pack == 'bootstrap4':
+                    offset_pattern = 'offset-%s-%s'
+                else:
+                    offset_pattern = 'col-%s-offset-%s'
+                items['bootstrap_checkbox_offsets'] = [offset_pattern % m for 
m in bootstrap_size_match]
+        else:
+            bootstrap_size_match = re.findall(r'col-(lg|md|sm|xs)-(\d+)', 
self.label_class)
+            if bootstrap_size_match:
+                if template_pack == 'bootstrap4':
+                    offset_pattern = 'offset-%s-%s'
+                else:
+                    offset_pattern = 'col-%s-offset-%s'
+                items['bootstrap_checkbox_offsets'] = [offset_pattern % m for 
m in bootstrap_size_match]
 
         items['attrs'] = {}
         if self.attrs:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-crispy-forms-1.7.2/crispy_forms/layout.py 
new/django-crispy-forms-1.8.0/crispy_forms/layout.py
--- old/django-crispy-forms-1.7.2/crispy_forms/layout.py        2017-10-17 
16:10:19.000000000 +0200
+++ new/django-crispy-forms-1.8.0/crispy_forms/layout.py        2019-10-17 
17:14:45.000000000 +0200
@@ -372,7 +372,16 @@
     """
 
     def __init__(self, *args, **kwargs):
-        self.css_class = 'formRow' if get_template_pack() == 'uni_form' else 
'row'
+        # Map template packs to the css class they need here.
+        # TODO: This is a _Smell_. There should be a factory which creates a
+        #       template pack specific subclass. (Or such...)
+        row_class_map = {
+            'uni_form': 'formRow',
+            'bootstrap4': 'form-row',
+            'bootstrap3': 'row',
+        }
+        # Fetch the class, with a suitable default.
+        self.css_class = row_class_map.get(get_template_pack(), 'row')
         super(Row, self).__init__(*args, **kwargs)
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-crispy-forms-1.7.2/crispy_forms/templates/bootstrap/layout/radioselect.html
 
new/django-crispy-forms-1.8.0/crispy_forms/templates/bootstrap/layout/radioselect.html
--- 
old/django-crispy-forms-1.7.2/crispy_forms/templates/bootstrap/layout/radioselect.html
      2018-03-05 15:49:56.000000000 +0100
+++ 
new/django-crispy-forms-1.8.0/crispy_forms/templates/bootstrap/layout/radioselect.html
      2019-10-10 06:46:48.000000000 +0200
@@ -5,8 +5,8 @@
     {% include 'bootstrap/layout/field_errors_block.html' %}
 
     {% for choice in field.field.choices %}
-        <label for="id_{{ field.id_for_label }}_{{ forloop.counter }}" 
class="radio{% if inline_class %} {{ inline_class }}{% endif %}">
-            <input type="radio"{% if choice.0|stringformat:"s" == 
field.value|default_if_none:""|stringformat:"s" %} checked="checked"{% endif %} 
name="{{ field.html_name }}" id="id_{{ field.id_for_label }}_{{ forloop.counter 
}}" value="{{ choice.0|unlocalize }}" {{ field.field.widget.attrs|flatatt }}>{{ 
choice.1|unlocalize }}
+        <label for="id_{{ field.html_name }}_{{ forloop.counter }}" 
class="radio{% if inline_class %} {{ inline_class }}{% endif %}">
+            <input type="radio"{% if choice.0|stringformat:"s" == 
field.value|default_if_none:""|stringformat:"s" %} checked="checked"{% endif %} 
name="{{ field.html_name }}" id="id_{{ field.html_name }}_{{ forloop.counter 
}}" value="{{ choice.0|unlocalize }}" {{ field.field.widget.attrs|flatatt }}>{{ 
choice.1|unlocalize }}
         </label>
     {% endfor %}
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-crispy-forms-1.7.2/crispy_forms/templates/bootstrap/uni_form.html 
new/django-crispy-forms-1.8.0/crispy_forms/templates/bootstrap/uni_form.html
--- 
old/django-crispy-forms-1.7.2/crispy_forms/templates/bootstrap/uni_form.html    
    2016-01-07 21:15:59.000000000 +0100
+++ 
new/django-crispy-forms-1.8.0/crispy_forms/templates/bootstrap/uni_form.html    
    2019-09-19 16:26:12.000000000 +0200
@@ -6,6 +6,6 @@
         {% include "bootstrap/errors.html" %}
     {% endif %}
     {% for field in form %}
-        {% include "bootstrap/field.html" %}
+        {% include field_template|default:"bootstrap/field.html" %}
     {% endfor %}
 {% endspecialspaceless %}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-crispy-forms-1.7.2/crispy_forms/templates/bootstrap3/layout/help_text.html
 
new/django-crispy-forms-1.8.0/crispy_forms/templates/bootstrap3/layout/help_text.html
--- 
old/django-crispy-forms-1.7.2/crispy_forms/templates/bootstrap3/layout/help_text.html
       2015-08-13 20:27:02.000000000 +0200
+++ 
new/django-crispy-forms-1.8.0/crispy_forms/templates/bootstrap3/layout/help_text.html
       2019-10-16 21:06:03.000000000 +0200
@@ -2,6 +2,6 @@
     {% if help_text_inline %}
         <span id="hint_{{ field.auto_id }}" class="help-block">{{ 
field.help_text|safe }}</span>
     {% else %}
-        <p id="hint_{{ field.auto_id }}" class="help-block">{{ 
field.help_text|safe }}</p>
+        <div id="hint_{{ field.auto_id }}" class="help-block">{{ 
field.help_text|safe }}</div>
     {% endif %}
 {% endif %}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-crispy-forms-1.7.2/crispy_forms/templates/bootstrap3/layout/prepended_appended_text.html
 
new/django-crispy-forms-1.8.0/crispy_forms/templates/bootstrap3/layout/prepended_appended_text.html
--- 
old/django-crispy-forms-1.7.2/crispy_forms/templates/bootstrap3/layout/prepended_appended_text.html
 2017-02-22 11:58:37.000000000 +0100
+++ 
new/django-crispy-forms-1.8.0/crispy_forms/templates/bootstrap3/layout/prepended_appended_text.html
 2019-09-19 16:26:12.000000000 +0200
@@ -12,17 +12,11 @@
         {% endif %}
 
         <div class="controls {{ field_class }}">
-            {% if field|is_select %}
-                {% if crispy_prepended_text %}<span class="input-group{% if 
active %} active{% endif %}{% if input_size %} {{ input_size }}{% endif %}">{{ 
crispy_prepended_text|safe }}</span>{% endif %}
+            <div class="input-group">
+                {% if crispy_prepended_text %}<span class="input-group-addon{% 
if active %} active{% endif %}{% if input_size %} {{ input_size }}{% endif 
%}">{{ crispy_prepended_text|safe }}</span>{% endif %}
                 {% crispy_field field %}
-                {% if crispy_appended_text %}<span class="input-group{% if 
active %} active{% endif %}{% if input_size %} {{ input_size }}{% endif %}">{{ 
crispy_appended_text|safe }}</span>{% endif %}
-            {% else %}
-                <div class="input-group">
-                    {% if crispy_prepended_text %}<span 
class="input-group-addon{% if active %} active{% endif %}{% if input_size %} {{ 
input_size }}{% endif %}">{{ crispy_prepended_text|safe }}</span>{% endif %}
-                    {% crispy_field field %}
-                    {% if crispy_appended_text %}<span 
class="input-group-addon{% if active %} active{% endif %}{% if input_size %} {{ 
input_size }}{% endif %}">{{ crispy_appended_text|safe }}</span>{% endif %}
-                </div>
-          {% endif %}
+                {% if crispy_appended_text %}<span class="input-group-addon{% 
if active %} active{% endif %}{% if input_size %} {{ input_size }}{% endif 
%}">{{ crispy_appended_text|safe }}</span>{% endif %}
+            </div>
 
             {% include 'bootstrap3/layout/help_text_and_errors.html' %}
         </div>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-crispy-forms-1.7.2/crispy_forms/templates/bootstrap3/layout/radioselect.html
 
new/django-crispy-forms-1.8.0/crispy_forms/templates/bootstrap3/layout/radioselect.html
--- 
old/django-crispy-forms-1.7.2/crispy_forms/templates/bootstrap3/layout/radioselect.html
     2018-03-05 15:49:56.000000000 +0100
+++ 
new/django-crispy-forms-1.8.0/crispy_forms/templates/bootstrap3/layout/radioselect.html
     2019-10-10 06:46:48.000000000 +0200
@@ -6,8 +6,8 @@
 
     {% for choice in field.field.choices %}
       {% if not inline_class %}<div class="radio">{% endif %}
-        <label for="id_{{ field.id_for_label }}_{{ forloop.counter }}" 
class="{% if inline_class %}radio-{{ inline_class }}{% endif %}">
-            <input type="radio"{% if choice.0|stringformat:"s" == 
field.value|default_if_none:""|stringformat:"s" %} checked="checked"{% endif %} 
name="{{ field.html_name }}" id="id_{{ field.id_for_label }}_{{ forloop.counter 
}}" value="{{ choice.0|unlocalize }}" {{ field.field.widget.attrs|flatatt }}>{{ 
choice.1|unlocalize }}
+        <label for="id_{{ field.html_name }}_{{ forloop.counter }}" class="{% 
if inline_class %}radio-{{ inline_class }}{% endif %}">
+            <input type="radio"{% if choice.0|stringformat:"s" == 
field.value|default_if_none:""|stringformat:"s" %} checked="checked"{% endif %} 
name="{{ field.html_name }}" id="id_{{ field.html_name }}_{{ forloop.counter 
}}" value="{{ choice.0|unlocalize }}" {{ field.field.widget.attrs|flatatt }}>{{ 
choice.1|unlocalize }}
         </label>
       {% if not inline_class %}</div>{% endif %}
     {% endfor %}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-crispy-forms-1.7.2/crispy_forms/templates/bootstrap3/table_inline_formset.html
 
new/django-crispy-forms-1.8.0/crispy_forms/templates/bootstrap3/table_inline_formset.html
--- 
old/django-crispy-forms-1.7.2/crispy_forms/templates/bootstrap3/table_inline_formset.html
   2017-10-17 16:10:19.000000000 +0200
+++ 
new/django-crispy-forms-1.8.0/crispy_forms/templates/bootstrap3/table_inline_formset.html
   2019-09-19 16:26:12.000000000 +0200
@@ -20,9 +20,9 @@
             {% else %}
                 <tr>
                     {% for field in formset.forms.0 %}
-                        {% if field.label and not field|is_checkbox and not 
field.is_hidden %}
+                        {% if field.label and not field.is_hidden %}
                             <th for="{{ field.auto_id }}" class="control-label 
{% if field.field.required %}requiredField{% endif %}">
-                                {{ field.label|safe }}{% if 
field.field.required %}<span class="asteriskField">*</span>{% endif %}
+                                {{ field.label|safe }}{% if 
field.field.required and not field|is_checkbox %}<span 
class="asteriskField">*</span>{% endif %}
                             </th>
                         {% endif %}
                     {% endfor %}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-crispy-forms-1.7.2/crispy_forms/templates/bootstrap3/uni_form.html 
new/django-crispy-forms-1.8.0/crispy_forms/templates/bootstrap3/uni_form.html
--- 
old/django-crispy-forms-1.7.2/crispy_forms/templates/bootstrap3/uni_form.html   
    2016-01-07 21:15:59.000000000 +0100
+++ 
new/django-crispy-forms-1.8.0/crispy_forms/templates/bootstrap3/uni_form.html   
    2019-09-19 16:26:12.000000000 +0200
@@ -6,6 +6,6 @@
         {% include "bootstrap3/errors.html" %}
     {% endif %}
     {% for field in form %}
-        {% include "bootstrap3/field.html" %}
+        {% include field_template|default:"bootstrap3/field.html" %}
     {% endfor %}
 {% endspecialspaceless %}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-crispy-forms-1.7.2/crispy_forms/templates/bootstrap4/accordion-group.html
 
new/django-crispy-forms-1.8.0/crispy_forms/templates/bootstrap4/accordion-group.html
--- 
old/django-crispy-forms-1.7.2/crispy_forms/templates/bootstrap4/accordion-group.html
        2016-01-07 21:15:59.000000000 +0100
+++ 
new/django-crispy-forms-1.8.0/crispy_forms/templates/bootstrap4/accordion-group.html
        2018-08-03 12:18:25.000000000 +0200
@@ -1,11 +1,16 @@
-<div class="panel panel-default">
-    <div class="panel-heading">
-        <h4 class="panel-title">
-            <a class="accordion-toggle" data-toggle="collapse" 
data-parent="#{{ div.data_parent }}" href="#{{ div.css_id }}">{{ div.name }}</a>
-        </h4>
+<div class="card mb-2">
+    <div class="card-header" role="tab">
+        <h5 class="mb-0">
+            <a data-toggle="collapse" href="#{{ div.css_id }}" 
aria-expanded="true"
+               aria-controls="{{ div.css_id }}">
+                {{ div.name }}
+            </a>
+        </h5>
     </div>
-    <div id="{{ div.css_id }}" class="panel-collapse collapse{% if div.active 
%} in{% endif %}" >
-        <div class="panel-body">
+
+    <div id="{{ div.css_id }}" class="collapse{% if div.active %} show{% endif 
%}" role="tabpanel"
+         aria-labelledby="{{ div.css_id }}" data-parent="#accordion">
+        <div class="card-body">
             {{ fields|safe }}
         </div>
     </div>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-crispy-forms-1.7.2/crispy_forms/templates/bootstrap4/accordion.html 
new/django-crispy-forms-1.8.0/crispy_forms/templates/bootstrap4/accordion.html
--- 
old/django-crispy-forms-1.7.2/crispy_forms/templates/bootstrap4/accordion.html  
    2016-01-07 21:15:59.000000000 +0100
+++ 
new/django-crispy-forms-1.8.0/crispy_forms/templates/bootstrap4/accordion.html  
    2018-08-03 12:18:25.000000000 +0200
@@ -1,3 +1,3 @@
-<div class="panel-group" id="{{ accordion.css_id }}">
+<div id="accordion" role="tablist">
     {{ content|safe }}
 </div>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-crispy-forms-1.7.2/crispy_forms/templates/bootstrap4/field.html 
new/django-crispy-forms-1.8.0/crispy_forms/templates/bootstrap4/field.html
--- old/django-crispy-forms-1.7.2/crispy_forms/templates/bootstrap4/field.html  
2018-03-09 15:40:03.000000000 +0100
+++ new/django-crispy-forms-1.8.0/crispy_forms/templates/bootstrap4/field.html  
2019-10-16 21:06:03.000000000 +0200
@@ -9,9 +9,9 @@
             <div class="{% for offset in bootstrap_checkbox_offsets %}{{ 
offset }} {% endfor %}{{ field_class }}">
         {% endif %}
     {% endif %}
-    <{% if tag %}{{ tag }}{% else %}div{% endif %} id="div_{{ field.auto_id 
}}" class="{% if not field|is_checkbox %}form-group{% if 'form-horizontal' in 
form_class %} row{% endif %}{% else %}form-check{% endif %}{% if wrapper_class 
%} {{ wrapper_class }}{% endif %}{% if field.css_classes %} {{ 
field.css_classes }}{% endif %}">
+    <{% if tag %}{{ tag }}{% else %}div{% endif %} id="div_{{ field.auto_id 
}}" class="{% if not field|is_checkbox %}form-group{% if 'form-horizontal' in 
form_class %} row{% endif %}{% else %}{%if use_custom_control%}custom-control 
custom-checkbox{% else %}form-check{% endif %}{% endif %}{% if wrapper_class %} 
{{ wrapper_class }}{% endif %}{% if field.css_classes %} {{ field.css_classes 
}}{% endif %}">
         {% if field.label and not field|is_checkbox and form_show_labels %}
-            <label for="{{ field.id_for_label }}" class="col-form-label {{ 
label_class }}{% if field.field.required %} requiredField{% endif %}">
+            <label for="{{ field.id_for_label }}" class="{% if 
'form-horizontal' in form_class %}col-form-label {% endif %}{{ label_class }}{% 
if field.field.required %} requiredField{% endif %}">
                 {{ field.label|safe }}{% if field.field.required %}<span 
class="asteriskField">*</span>{% endif %}
             </label>
         {% endif %}
@@ -26,11 +26,17 @@
 
         {% if not field|is_checkboxselectmultiple and not field|is_radioselect 
%}
             {% if field|is_checkbox and form_show_labels %}
-                <label for="{{ field.id_for_label }}" 
class="form-check-label{% if field.field.required %} requiredField{% endif %}">
+                {%if use_custom_control%}
+                    {% crispy_field field 'class' 'custom-control-input' %}
+                {% else %}
                     {% crispy_field field 'class' 'form-check-input' %}
+                {% endif %}
+                <label for="{{ field.id_for_label }}" class="{%if 
use_custom_control%}custom-control-label{% else %}form-check-label{% endif %}{% 
if field.field.required %} requiredField{% endif %}">
                     {{ field.label|safe }}{% if field.field.required %}<span 
class="asteriskField">*</span>{% endif %}
                 </label>
                 {% include 'bootstrap4/layout/help_text_and_errors.html' %}
+            {% elif field|is_file %}
+                {% include 'bootstrap4/layout/field_file.html' %}
             {% else %}
                 <div class="{{ field_class }}">
                     {% crispy_field field %}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-crispy-forms-1.7.2/crispy_forms/templates/bootstrap4/layout/checkboxselectmultiple.html
 
new/django-crispy-forms-1.8.0/crispy_forms/templates/bootstrap4/layout/checkboxselectmultiple.html
--- 
old/django-crispy-forms-1.7.2/crispy_forms/templates/bootstrap4/layout/checkboxselectmultiple.html
  2018-03-09 15:40:03.000000000 +0100
+++ 
new/django-crispy-forms-1.8.0/crispy_forms/templates/bootstrap4/layout/checkboxselectmultiple.html
  2019-10-16 21:06:03.000000000 +0200
@@ -1,17 +1,26 @@
 {% load crispy_forms_filters %}
 {% load l10n %}
 
-<div class="{% if inline_class %}form-check{% endif %}{% if field_class %} {{ 
field_class }}{% endif %}"{% if flat_attrs %} {{ flat_attrs|safe }}{% endif %}>
-    {% include 'bootstrap4/layout/field_errors_block.html' %}
+<div class="{% if field_class %} {{ field_class }}{% endif %}"{% if flat_attrs 
%} {{ flat_attrs|safe }}{% endif %}>
 
     {% for choice in field.field.choices %}
-        {% if not inline_class %}<div class="form-check">{% endif %}
-        <label id="id_{{ field.id_for_label }}_{{ forloop.counter }}" 
class="form-check-{% if inline_class %}{{ inline_class }}{% else %}label{% 
endif %}" for="id_{{ field.html_name }}_{{ forloop.counter }}">
-            <input type="checkbox" class="form-check-input"{% if choice.0 in 
field.value or choice.0|stringformat:"s" in field.value or 
choice.0|stringformat:"s" == field.value|default_if_none:""|stringformat:"s" %} 
checked="checked"{% endif %} name="{{ field.html_name }}" id="id_{{ 
field.html_name }}_{{ forloop.counter }}" value="{{ choice.0|unlocalize }}" {{ 
field.field.widget.attrs|flatatt }}>
+    <div class="{%if use_custom_control%}custom-control custom-checkbox{% if 
inline_class %} custom-control-inline{% endif %}{% else %}form-check{% if 
inline_class %} form-check-inline{% endif %}{% endif %}">
+        <input type="checkbox" class="{%if 
use_custom_control%}custom-control-input{% else %}form-check-input{% endif 
%}{%if is_bound %} is-{% if field.errors %}in{%endif%}valid{% endif %}"{% if 
choice.0 in field.value or choice.0|stringformat:"s" in field.value or 
choice.0|stringformat:"s" == field.value|default_if_none:""|stringformat:"s" %} 
checked="checked"{% endif %} name="{{ field.html_name }}" id="id_{{ 
field.html_name }}_{{ forloop.counter }}" value="{{ choice.0|unlocalize }}" {{ 
field.field.widget.attrs|flatatt }}>
+        <label class="{%if use_custom_control%}custom-control-label{% else 
%}form-check-label{% endif %}" for="id_{{ field.html_name }}_{{ forloop.counter 
}}">
             {{ choice.1|unlocalize }}
         </label>
-      {% if not inline_class %}</div>{% endif %}
-    {% endfor %}
+        {% if field.errors and forloop.last and not inline_class %}
+            {% include 'bootstrap4/layout/field_errors_block.html' %}
+            {% endif %}
+    </div>
+   {% endfor %}
+    {% if field.errors and inline_class %}
+    <div class="w-100 {%if use_custom_control%}custom-control 
custom-checkbox{% if inline_class %} custom-control-inline{% endif %}{% else 
%}form-check{% if inline_class %} form-check-inline{% endif %}{% endif %}">
+        {# the following input is only meant to allow boostrap to render the 
error message as it has to be after an invalid input. As the input has no name, 
no data will be sent. #}
+        <input type="checkbox" class="custom-control-input {% if field.errors 
%}is-invalid{%endif%}">
+        {% include 'bootstrap4/layout/field_errors_block.html' %}
+    </div>
+    {% endif %}
 
     {% include 'bootstrap4/layout/help_text.html' %}
-</div>
+</div>
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-crispy-forms-1.7.2/crispy_forms/templates/bootstrap4/layout/checkboxselectmultiple_inline.html
 
new/django-crispy-forms-1.8.0/crispy_forms/templates/bootstrap4/layout/checkboxselectmultiple_inline.html
--- 
old/django-crispy-forms-1.7.2/crispy_forms/templates/bootstrap4/layout/checkboxselectmultiple_inline.html
   2018-03-05 15:49:56.000000000 +0100
+++ 
new/django-crispy-forms-1.8.0/crispy_forms/templates/bootstrap4/layout/checkboxselectmultiple_inline.html
   2019-10-16 21:06:03.000000000 +0200
@@ -4,7 +4,7 @@
     <div id="div_{{ field.auto_id }}" class="form-group{% if 'form-horizontal' 
in form_class %} row{% endif %}{% if wrapper_class %} {{ wrapper_class }}{% 
endif %}{% if form_show_errors and field.errors %} has-danger{% endif %}{% if 
field.css_classes %} {{ field.css_classes }}{% endif %}">
 
         {% if field.label %}
-            <label for="{{ field.auto_id }}"  class="{{ label_class }}{% if 
not inline_class %} col-form-label{% endif %}{% if field.field.required %} 
requiredField{% endif %}">
+            <label for="{{ field.id_for_label }}"  class="{{ label_class }}{% 
if not inline_class %} col-form-label{% endif %}{% if field.field.required %} 
requiredField{% endif %}">
                 {{ field.label|safe }}{% if field.field.required %}<span 
class="asteriskField">*</span>{% endif %}
             </label>
         {% endif %}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-crispy-forms-1.7.2/crispy_forms/templates/bootstrap4/layout/field_file.html
 
new/django-crispy-forms-1.8.0/crispy_forms/templates/bootstrap4/layout/field_file.html
--- 
old/django-crispy-forms-1.7.2/crispy_forms/templates/bootstrap4/layout/field_file.html
      1970-01-01 01:00:00.000000000 +0100
+++ 
new/django-crispy-forms-1.8.0/crispy_forms/templates/bootstrap4/layout/field_file.html
      2019-10-16 21:06:03.000000000 +0200
@@ -0,0 +1,7 @@
+{% load crispy_forms_field %}
+
+<div class="custom-file {{ field_class }}">
+    {% crispy_field field 'class' 'custom-file-input' %}
+    <label class="custom-file-label" for="{{ field.id_for_label }}">Choose 
file</label>
+    {% include 'bootstrap4/layout/help_text_and_errors.html' %}
+</div>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-crispy-forms-1.7.2/crispy_forms/templates/bootstrap4/layout/field_with_buttons.html
 
new/django-crispy-forms-1.8.0/crispy_forms/templates/bootstrap4/layout/field_with_buttons.html
--- 
old/django-crispy-forms-1.7.2/crispy_forms/templates/bootstrap4/layout/field_with_buttons.html
      2018-03-09 15:40:03.000000000 +0100
+++ 
new/django-crispy-forms-1.8.0/crispy_forms/templates/bootstrap4/layout/field_with_buttons.html
      2019-10-10 06:46:48.000000000 +0200
@@ -2,7 +2,7 @@
 
 <div{% if div.css_id %} id="{{ div.css_id }}"{% endif %} class="form-group{% 
if 'form-horizontal' in form_class %} row{% endif %}{% if wrapper_class %} {{ 
wrapper_class }}{% endif %}{% if form_show_errors and field.errors %} 
has-danger{% endif %}{% if field.css_classes %} {{ field.css_classes }}{% endif 
%}{% if div.css_class %} {{ div.css_class }}{% endif %}" {{ div.flat_attrs|safe 
}}>
     {% if field.label and form_show_labels %}
-        <label for="{{ field.id_for_label }}" class="col-form-label {{ 
label_class }}{% if field.field.required %} requiredField{% endif %}">
+        <label for="{{ field.id_for_label }}" class="{% if 'form-horizontal' 
in form_class %}col-form-label {% endif %}{{ label_class }}{% if 
field.field.required %} requiredField{% endif %}">
             {{ field.label|safe }}{% if field.field.required %}<span 
class="asteriskField">*</span>{% endif %}
         </label>
     {% endif %}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-crispy-forms-1.7.2/crispy_forms/templates/bootstrap4/layout/prepended_appended_text.html
 
new/django-crispy-forms-1.8.0/crispy_forms/templates/bootstrap4/layout/prepended_appended_text.html
--- 
old/django-crispy-forms-1.7.2/crispy_forms/templates/bootstrap4/layout/prepended_appended_text.html
 2018-03-05 15:49:56.000000000 +0100
+++ 
new/django-crispy-forms-1.8.0/crispy_forms/templates/bootstrap4/layout/prepended_appended_text.html
 2019-10-10 06:46:48.000000000 +0200
@@ -6,33 +6,33 @@
     <div id="div_{{ field.auto_id }}" class="form-group{% if wrapper_class %} 
{{ wrapper_class }}{% endif %}{% if 'form-horizontal' in form_class %} row{% 
endif %}{% if form_group_wrapper_class %} {{ form_group_wrapper_class }}{% 
endif %}{% if form_show_errors and field.errors %} has-danger{% endif %}{% if 
field.css_classes %} {{ field.css_classes }}{% endif %}">
 
         {% if field.label and form_show_labels %}
-            <label for="{{ field.id_for_label }}" class="col-form-label {{ 
label_class }}{% if field.field.required %} requiredField{% endif %}">
+            <label for="{{ field.id_for_label }}" class="{% if 
'form-horizontal' in form_class %}col-form-label {% endif %}{{ label_class }}{% 
if field.field.required %} requiredField{% endif %}">
                 {{ field.label|safe }}{% if field.field.required %}<span 
class="asteriskField">*</span>{% endif %}
             </label>
         {% endif %}
 
         <div class="{{ field_class }}">
-            {% if field|is_select %}
-                {% if crispy_prepended_text %}<span class="input-group{% if 
active %} active{% endif %}{% if input_size %} {{ input_size }}{% endif %}">{{ 
crispy_prepended_text|safe }}</span>{% endif %}
+            <div class="input-group">
+                {% if crispy_prepended_text %}
+                  <div class="input-group-prepend{% if active %} active{% 
endif %}{% if input_size %} {{ input_size }}{% endif %}">
+                    <span class="input-group-text">{{ 
crispy_prepended_text|safe }}</span>
+                  </div>
+                {% endif %}
                 {% crispy_field field %}
-                {% if crispy_appended_text %}<span class="input-group{% if 
active %} active{% endif %}{% if input_size %} {{ input_size }}{% endif %}">{{ 
crispy_appended_text|safe }}</span>{% endif %}
-            {% else %}
-                <div class="input-group">
-                    {% if crispy_prepended_text %}
-                      <div class="input-group-prepend{% if active %} active{% 
endif %}{% if input_size %} {{ input_size }}{% endif %}">
-                        <span class="input-group-text">{{ 
crispy_prepended_text|safe }}</span>
-                      </div>
-                    {% endif %}
-                    {% crispy_field field %}
-                    {% if crispy_appended_text %}
-                      <div class="input-group-append{% if active %} active{% 
endif %}{% if input_size %} {{ input_size }}{% endif %}">
-                        <span class="input-group-text">{{ 
crispy_appended_text|safe }}</span>
-                      </div>
-                    {% endif %}
-                </div>
-            {% endif %}
-
-            {% include 'bootstrap4/layout/help_text_and_errors.html' %}
+                {% if crispy_appended_text %}
+                  <div class="input-group-append{% if active %} active{% endif 
%}{% if input_size %} {{ input_size }}{% endif %}">
+                    <span class="input-group-text">{{ 
crispy_appended_text|safe }}</span>
+                  </div>
+                {% endif %}
+                {% if error_text_inline %}
+                    {% include 'bootstrap4/layout/field_errors.html' %}
+                {% else %}
+                    {% include 'bootstrap4/layout/field_errors_block.html' %}
+                {% endif %}
+            </div>
+        {% if not help_text_inline %}
+            {% include 'bootstrap4/layout/help_text.html' %}
+        {% endif %}
         </div>
 
     </div>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-crispy-forms-1.7.2/crispy_forms/templates/bootstrap4/layout/radioselect.html
 
new/django-crispy-forms-1.8.0/crispy_forms/templates/bootstrap4/layout/radioselect.html
--- 
old/django-crispy-forms-1.7.2/crispy_forms/templates/bootstrap4/layout/radioselect.html
     2018-03-05 15:49:56.000000000 +0100
+++ 
new/django-crispy-forms-1.8.0/crispy_forms/templates/bootstrap4/layout/radioselect.html
     2019-10-16 21:06:03.000000000 +0200
@@ -1,17 +1,26 @@
 {% load crispy_forms_filters %}
 {% load l10n %}
 
-<div class="{% if inline_class %}form-check{% endif %}{% if field_class %} {{ 
field_class }}{% endif %}"{% if flat_attrs %} {{ flat_attrs|safe }}{% endif %}>
-    {% include 'bootstrap4/layout/field_errors_block.html' %}
+<div class="{% if field_class %} {{ field_class }}{% endif %}"{% if flat_attrs 
%} {{ flat_attrs|safe }}{% endif %}>
 
     {% for choice in field.field.choices %}
-      {% if not inline_class %}<div class="form-check">{% endif %}
-        <label for="id_{{ field.id_for_label }}_{{ forloop.counter }}" 
class="form-check-{% if inline_class %}{{ inline_class }}{% else %}label{% 
endif %}">
-            <input type="radio" class="form-check-input"{% if 
choice.0|stringformat:"s" == field.value|default_if_none:""|stringformat:"s" %} 
checked="checked"{% endif %} name="{{ field.html_name }}" id="id_{{ 
field.id_for_label }}_{{ forloop.counter }}" value="{{ choice.0|unlocalize }}" 
{{ field.field.widget.attrs|flatatt }}>
+      <div class="{%if use_custom_control%}custom-control custom-radio{% if 
inline_class %} custom-control-inline{% endif %}{% else %}form-check{% if 
inline_class %} form-check-inline{% endif %}{% endif %}">
+        <input type="radio" class="{%if 
use_custom_control%}custom-control-input{% else %}form-check-input{% endif 
%}{%if is_bound %} is-{% if field.errors %}in{%endif%}valid{% endif %}"{% if 
choice.0|stringformat:"s" == field.value|default_if_none:""|stringformat:"s" %} 
checked="checked"{% endif %} name="{{ field.html_name }}" id="id_{{ 
field.html_name }}_{{ forloop.counter }}" value="{{ choice.0|unlocalize }}" {{ 
field.field.widget.attrs|flatatt }}>
+        <label for="id_{{ field.html_name }}_{{ forloop.counter }}" 
class="{%if use_custom_control%}custom-control-label{% else 
%}form-check-label{% endif %}">
             {{ choice.1|unlocalize }}
         </label>
-      {% if not inline_class %}</div>{% endif %}
+        {% if field.errors and forloop.last and not inline_class %}
+            {% include 'bootstrap4/layout/field_errors_block.html' %}
+        {% endif %}
+     </div>
     {% endfor %}
+    {% if field.errors and inline_class %}
+    <div class="w-100 {%if use_custom_control%}custom-control custom-radio{% 
if inline_class %} custom-control-inline{% endif %}{% else %}form-check{% if 
inline_class %} form-check-inline{% endif %}{% endif %}">
+        {# the following input is only meant to allow boostrap to render the 
error message as it has to be after an invalid input. As the input has no name, 
no data will be sent. #}
+        <input type="checkbox" class="custom-control-input {% if field.errors 
%}is-invalid{%endif%}">
+        {% include 'bootstrap4/layout/field_errors_block.html' %}
+    </div>
+    {% endif %}
 
     {% include 'bootstrap4/layout/help_text.html' %}
 </div>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-crispy-forms-1.7.2/crispy_forms/templates/bootstrap4/layout/radioselect_inline.html
 
new/django-crispy-forms-1.8.0/crispy_forms/templates/bootstrap4/layout/radioselect_inline.html
--- 
old/django-crispy-forms-1.7.2/crispy_forms/templates/bootstrap4/layout/radioselect_inline.html
      2018-03-05 15:49:56.000000000 +0100
+++ 
new/django-crispy-forms-1.8.0/crispy_forms/templates/bootstrap4/layout/radioselect_inline.html
      2019-10-16 21:06:03.000000000 +0200
@@ -4,7 +4,7 @@
     <div id="div_{{ field.auto_id }}" class="form-group{% if 'form-horizontal' 
in form_class %} row{% endif %}{% if wrapper_class %} {{ wrapper_class }}{% 
endif %}{% if form_show_errors and field.errors %} has-danger{% endif %}{% if 
field.css_classes %} {{ field.css_classes }}{% endif %}">
 
         {% if field.label %}
-            <label for="{{ field.auto_id }}"  class="{{ label_class }}{% if 
not inline_class %} col-form-label{% endif %}{% if field.field.required %} 
requiredField{% endif %}">
+            <label for="{{ field.id_for_label }}"  class="{{ label_class }}{% 
if not inline_class %} col-form-label{% endif %}{% if field.field.required %} 
requiredField{% endif %}">
                 {{ field.label|safe }}{% if field.field.required %}<span 
class="asteriskField">*</span>{% endif %}
             </label>
         {% endif %}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-crispy-forms-1.7.2/crispy_forms/templates/bootstrap4/layout/tab.html 
new/django-crispy-forms-1.8.0/crispy_forms/templates/bootstrap4/layout/tab.html
--- 
old/django-crispy-forms-1.7.2/crispy_forms/templates/bootstrap4/layout/tab.html 
    2016-01-07 21:15:59.000000000 +0100
+++ 
new/django-crispy-forms-1.8.0/crispy_forms/templates/bootstrap4/layout/tab.html 
    2019-09-19 16:26:12.000000000 +0200
@@ -1,6 +1,6 @@
 <ul{% if tabs.css_id %} id="{{ tabs.css_id }}"{% endif %} class="nav nav-tabs">
     {{ links|safe }}
 </ul>
-<div class="tab-content panel-body">
+<div class="tab-content card-body">
     {{ content|safe }}
 </div>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-crispy-forms-1.7.2/crispy_forms/templates/bootstrap4/layout/uneditable_input.html
 
new/django-crispy-forms-1.8.0/crispy_forms/templates/bootstrap4/layout/uneditable_input.html
--- 
old/django-crispy-forms-1.7.2/crispy_forms/templates/bootstrap4/layout/uneditable_input.html
        2018-03-05 15:49:56.000000000 +0100
+++ 
new/django-crispy-forms-1.8.0/crispy_forms/templates/bootstrap4/layout/uneditable_input.html
        2019-10-10 06:46:48.000000000 +0200
@@ -2,7 +2,7 @@
 
 
 <div id="div_{{ field.auto_id }}" class="form-group{% if 'form-horizontal' in 
form_class %} row{% endif %}{% if form_show_errors and field.errors %} error{% 
endif %}{% if field.css_classes %} {{ field.css_classes }}{% endif %}">
-    <label class="col-form-label {{ label_class }}{% if field.field.required 
%} requiredField{% endif %}">{{ field.label|safe }}{% if field.field.required 
%}<span class="asteriskField">*</span>{% endif %}</label>
+    <label class="{% if 'form-horizontal' in form_class %}col-form-label {% 
endif %}{{ label_class }}{% if field.field.required %} requiredField{% endif 
%}">{{ field.label|safe }}{% if field.field.required %}<span 
class="asteriskField">*</span>{% endif %}</label>
     <div class="{{ field_class }}">
         {% crispy_field field 'disabled' 'disabled' %}
         {% include 'bootstrap4/layout/help_text.html' %}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-crispy-forms-1.7.2/crispy_forms/templates/bootstrap4/table_inline_formset.html
 
new/django-crispy-forms-1.8.0/crispy_forms/templates/bootstrap4/table_inline_formset.html
--- 
old/django-crispy-forms-1.7.2/crispy_forms/templates/bootstrap4/table_inline_formset.html
   2018-03-05 15:49:56.000000000 +0100
+++ 
new/django-crispy-forms-1.8.0/crispy_forms/templates/bootstrap4/table_inline_formset.html
   2019-09-19 16:26:12.000000000 +0200
@@ -20,9 +20,9 @@
             {% else %}
                 <tr>
                     {% for field in formset.forms.0 %}
-                        {% if field.label and not field|is_checkbox and not 
field.is_hidden %}
+                        {% if field.label and not field.is_hidden %}
                             <th for="{{ field.auto_id }}" 
class="col-form-label {% if field.field.required %}requiredField{% endif %}">
-                                {{ field.label|safe }}{% if 
field.field.required %}<span class="asteriskField">*</span>{% endif %}
+                                {{ field.label|safe }}{% if 
field.field.required and not field|is_checkbox %}<span 
class="asteriskField">*</span>{% endif %}
                             </th>
                         {% endif %}
                     {% endfor %}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-crispy-forms-1.7.2/crispy_forms/templates/bootstrap4/uni_form.html 
new/django-crispy-forms-1.8.0/crispy_forms/templates/bootstrap4/uni_form.html
--- 
old/django-crispy-forms-1.7.2/crispy_forms/templates/bootstrap4/uni_form.html   
    2016-01-07 21:15:59.000000000 +0100
+++ 
new/django-crispy-forms-1.8.0/crispy_forms/templates/bootstrap4/uni_form.html   
    2019-09-19 16:26:12.000000000 +0200
@@ -6,6 +6,6 @@
         {% include "bootstrap4/errors.html" %}
     {% endif %}
     {% for field in form %}
-        {% include "bootstrap4/field.html" %}
+        {% include field_template|default:"bootstrap4/field.html" %}
     {% endfor %}
 {% endspecialspaceless %}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-crispy-forms-1.7.2/crispy_forms/templates/uni_form/uni_form.html 
new/django-crispy-forms-1.8.0/crispy_forms/templates/uni_form/uni_form.html
--- old/django-crispy-forms-1.7.2/crispy_forms/templates/uni_form/uni_form.html 
2016-01-07 21:15:59.000000000 +0100
+++ new/django-crispy-forms-1.8.0/crispy_forms/templates/uni_form/uni_form.html 
2019-09-19 16:26:12.000000000 +0200
@@ -9,7 +9,7 @@
 {% endif %}
 
 {% for field in form %}
-    {% include "uni_form/field.html" %}
+    {% include field_template|default:"uni_form/field.html" %}
 {% endfor %}
 
 {% if form_style == "" or form_style %}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-crispy-forms-1.7.2/crispy_forms/templatetags/crispy_forms_field.py 
new/django-crispy-forms-1.8.0/crispy_forms/templatetags/crispy_forms_field.py
--- 
old/django-crispy-forms-1.7.2/crispy_forms/templatetags/crispy_forms_field.py   
    2018-03-05 15:49:56.000000000 +0100
+++ 
new/django-crispy-forms-1.8.0/crispy_forms/templatetags/crispy_forms_field.py   
    2019-10-16 21:06:03.000000000 +0200
@@ -128,14 +128,13 @@
                 css_class += ' form-control'
                 if field.errors:
                     css_class += ' form-control-danger'
-            
+
             if (
                 template_pack == 'bootstrap4'
-                and not is_checkbox(field)
-                and not is_file(field)
                 and not is_multivalue(field)
             ):
-                css_class += ' form-control'
+                if not is_checkbox(field):
+                    css_class += ' form-control'
                 if field.errors:
                     css_class += ' is-invalid'
 
@@ -154,7 +153,7 @@
                 else:
                     widget.attrs[attribute_name] = 
template.Variable(attribute).resolve(context)
 
-        return field
+        return str(field)
 
 
 @register.tag(name="crispy_field")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-crispy-forms-1.7.2/crispy_forms/templatetags/crispy_forms_filters.py 
new/django-crispy-forms-1.8.0/crispy_forms/templatetags/crispy_forms_filters.py
--- 
old/django-crispy-forms-1.7.2/crispy_forms/templatetags/crispy_forms_filters.py 
    2017-10-17 16:10:19.000000000 +0200
+++ 
new/django-crispy-forms-1.8.0/crispy_forms/templatetags/crispy_forms_filters.py 
    2019-10-10 06:46:48.000000000 +0200
@@ -5,9 +5,9 @@
 from django.forms.formsets import BaseFormSet
 from django.template import Context
 from django.template.loader import get_template
-from django.utils.lru_cache import lru_cache
 from django.utils.safestring import mark_safe
 
+from crispy_forms.compatibility import lru_cache
 from crispy_forms.exceptions import CrispyError
 from crispy_forms.utils import TEMPLATE_PACK, flatatt
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-crispy-forms-1.7.2/crispy_forms/templatetags/crispy_forms_tags.py 
new/django-crispy-forms-1.8.0/crispy_forms/templatetags/crispy_forms_tags.py
--- 
old/django-crispy-forms-1.7.2/crispy_forms/templatetags/crispy_forms_tags.py    
    2017-10-17 16:10:19.000000000 +0200
+++ 
new/django-crispy-forms-1.8.0/crispy_forms/templatetags/crispy_forms_tags.py    
    2019-10-10 06:46:48.000000000 +0200
@@ -3,9 +3,8 @@
 from django.conf import settings
 from django.forms.formsets import BaseFormSet
 from django.template.loader import get_template
-from django.utils.lru_cache import lru_cache
 
-from crispy_forms.compatibility import string_types
+from crispy_forms.compatibility import lru_cache, string_types
 from crispy_forms.helper import FormHelper
 from crispy_forms.utils import TEMPLATE_PACK, get_template_pack
 
@@ -109,6 +108,7 @@
         is_formset = isinstance(actual_form, BaseFormSet)
         response_dict = self.get_response_dict(helper, context, is_formset)
         node_context = context.__copy__()
+        node_context.update({'is_bound': actual_form.is_bound})
         node_context.update(response_dict)
         final_context = node_context.__copy__()
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-crispy-forms-1.7.2/crispy_forms/tests/conftest.py 
new/django-crispy-forms-1.8.0/crispy_forms/tests/conftest.py
--- old/django-crispy-forms-1.7.2/crispy_forms/tests/conftest.py        
2017-10-17 16:10:19.000000000 +0200
+++ new/django-crispy-forms-1.8.0/crispy_forms/tests/conftest.py        
2019-09-19 16:26:12.000000000 +0200
@@ -32,12 +32,12 @@
 @pytest.fixture(autouse=True, params=('uni_form', 'bootstrap', 'bootstrap3',
                                       'bootstrap4'))
 def template_packs(request, settings):
-    check_template_pack(request._pyfuncitem._obj, request.param)
+    check_template_pack(request.node, request.param)
     settings.CRISPY_TEMPLATE_PACK = request.param
 
 
-def check_template_pack(function, template_pack):
-    if hasattr(function, 'only'):
-        mark = function.only
+def check_template_pack(node, template_pack):
+    mark = node.get_closest_marker('only')
+    if mark:
         if template_pack not in mark.args:
             pytest.skip('Requires %s template pack' % ' or '.join(mark.args))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-crispy-forms-1.7.2/crispy_forms/tests/test_form_helper.py 
new/django-crispy-forms-1.8.0/crispy_forms/tests/test_form_helper.py
--- old/django-crispy-forms-1.7.2/crispy_forms/tests/test_form_helper.py        
2018-03-05 15:49:56.000000000 +0100
+++ new/django-crispy-forms-1.8.0/crispy_forms/tests/test_form_helper.py        
2019-10-16 21:06:03.000000000 +0200
@@ -69,8 +69,10 @@
         assert 'class="btn"' in html
         assert 'btn btn-primary' in html
         assert 'btn btn-inverse' in html
-        assert len(re.findall(r'<input[^>]+> <', html)) == 8
-
+        if settings.CRISPY_TEMPLATE_PACK == 'bootstrap4':
+            assert len(re.findall(r'<input[^>]+> <', html)) == 9
+        else:
+            assert len(re.findall(r'<input[^>]+> <', html)) == 8
 
 def test_invalid_form_method():
     form_helper = FormHelper()
@@ -389,7 +391,7 @@
     html = template.render(c)
 
     assert html.count('<form') == 1
-    assert html.count("<input type='hidden' name='csrfmiddlewaretoken'") == 1
+    assert html.count('csrfmiddlewaretoken') == 1
 
     # Check formset management form
     assert 'form-TOTAL_FORMS' in html
@@ -417,7 +419,7 @@
     c = Context({'form': SampleForm(), 'form_helper': form_helper, 
'csrf_token': _get_new_csrf_key()})
     html = template.render(c)
 
-    assert "<input type='hidden' name='csrfmiddlewaretoken'" in html
+    assert 'csrfmiddlewaretoken' in html
 
 
 def test_CSRF_token_GET_form():
@@ -431,7 +433,7 @@
     c = Context({'form': SampleForm(), 'form_helper': form_helper, 
'csrf_token': _get_new_csrf_key()})
     html = template.render(c)
 
-    assert "<input type='hidden' name='csrfmiddlewaretoken'" not in html
+    assert 'csrfmiddlewaretoken' not in html
 
 
 def test_disable_csrf():
@@ -500,6 +502,26 @@
     assert html.count("<h1>Special custom field</h1>") == 2
 
 
+def test_helper_custom_field_template_no_layout():
+    form = SampleForm()
+    form.helper = FormHelper()
+    form.helper.field_template = 'custom_field_template.html'
+
+    html = render_crispy_form(form)
+    for field in form.fields:
+        assert html.count('id="div_id_%s"' % field) == 1
+    assert html.count("<h1>Special custom field</h1>") == len(form.fields)
+
+
+def test_helper_std_field_template_no_layout():
+    form = SampleForm()
+    form.helper = FormHelper()
+
+    html = render_crispy_form(form)
+    for field in form.fields:
+        assert html.count('id="div_id_%s"' % field) == 1
+
+
 @only_uni_form
 def test_form_show_errors():
     form = SampleForm({
@@ -632,7 +654,7 @@
         help_tag_name = 'div'
 
     matches = re.findall(
-        '<span id="error_\d_\w*" class="%s"' % help_class, html, re.MULTILINE
+        r'<span id="error_\d_\w*" class="%s"' % help_class, html, re.MULTILINE
     )
     assert len(matches) == 3
 
@@ -649,7 +671,7 @@
         help_tag_name = 'p'
 
     matches = re.findall(
-        '<%s id="error_\d_\w*" class="%s"' % (help_tag_name, help_class),
+        r'<%s id="error_\d_\w*" class="%s"' % (help_tag_name, help_class),
         html,
         re.MULTILINE
     )
@@ -657,7 +679,7 @@
 
 
 @only_bootstrap3
-def test_error_and_help_inline():
+def test_error_and_help_inline_bootstrap3():
     form = SampleForm({'email': 'invalidemail'})
     form.helper = FormHelper()
     form.helper.error_text_inline = False
@@ -682,7 +704,7 @@
 
     # Check that error goes before help, otherwise CSS won't work
     error_position = html.find('<span id="error_1_id_email" 
class="help-inline">')
-    help_position = html.find('<p id="hint_id_email" class="help-block">')
+    help_position = html.find('<div id="hint_id_email" class="help-block">')
     assert error_position < help_position
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-crispy-forms-1.7.2/crispy_forms/tests/test_layout.py 
new/django-crispy-forms-1.8.0/crispy_forms/tests/test_layout.py
--- old/django-crispy-forms-1.7.2/crispy_forms/tests/test_layout.py     
2018-03-05 15:49:56.000000000 +0100
+++ new/django-crispy-forms-1.8.0/crispy_forms/tests/test_layout.py     
2019-10-17 17:14:45.000000000 +0200
@@ -6,7 +6,7 @@
 import django
 from django import forms
 from django.forms.models import formset_factory, modelformset_factory
-from django.shortcuts import render_to_response
+from django.shortcuts import render
 from django.template import Context, Template
 from django.utils.translation import ugettext_lazy as _
 
@@ -207,6 +207,8 @@
 
     if settings.CRISPY_TEMPLATE_PACK == 'uni_form':
         assert 'class="formRow rows"' in html
+    elif settings.CRISPY_TEMPLATE_PACK == 'bootstrap4':
+        assert 'class="form-row rows"' in html
     else:
         assert 'class="row rows"' in html
     assert 'Hello!' in html
@@ -293,7 +295,7 @@
 
     # Check form structure
     assert html.count('<form') == 1
-    assert html.count("<input type='hidden' name='csrfmiddlewaretoken'") == 1
+    assert html.count('csrfmiddlewaretoken') == 1
     assert 'formsets-that-rock' in html
     assert 'method="post"' in html
     assert 'id="thisFormsetRocks"' in html
@@ -555,14 +557,62 @@
     )
     context = {'form': form}
 
-    response = render_to_response('crispy_render_template.html', context)
+    response = render(
+        request=None,
+        template_name='crispy_render_template.html',
+        context=context
+    )
 
     if settings.CRISPY_TEMPLATE_PACK == 'bootstrap':
         assert response.content.count(b'checkbox inline') == 3
     elif settings.CRISPY_TEMPLATE_PACK == 'bootstrap3':
         assert response.content.count(b'checkbox-inline') == 3
     elif settings.CRISPY_TEMPLATE_PACK == 'bootstrap4':
-        assert response.content.count(b'form-check-inline') == 3
+        assert response.content.count(b'custom-control-inline') == 3
+        assert response.content.count(b'custom-checkbox') > 0
+
+
+@only_bootstrap4
+def test_use_custom_control_is_used():
+    form = CheckboxesSampleForm()
+    form.helper = FormHelper()
+    form.helper.layout = Layout(
+        'checkboxes',
+        InlineCheckboxes('alphacheckboxes'),
+        'numeric_multiple_checkboxes'
+    )
+    # form.helper.use_custom_control take default value which is True
+
+    response = render(
+        request=None,
+        template_name='crispy_render_template.html',
+        context={'form': form}
+    )
+    assert response.content.count(b'custom-control-inline') == 3
+    assert response.content.count(b'custom-checkbox') == 9
+
+    form.helper.use_custom_control = True
+
+    response = render(
+        request=None,
+        template_name='crispy_render_template.html',
+        context={'form': form}
+    )
+    assert response.content.count(b'custom-control-inline') == 3
+    assert response.content.count(b'custom-checkbox') == 9
+
+    form.helper.use_custom_control = False
+
+    response = render(
+        request=None,
+        template_name='crispy_render_template.html',
+        context={'form': form}
+    )
+
+    assert response.content.count(b'custom-control-inline') == 0
+    assert response.content.count(b'form-check-inline') == 3
+    assert response.content.count(b'form-check') > 0
+    assert response.content.count(b'custom-checkbox') == 0
 
 
 @only_bootstrap3
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-crispy-forms-1.7.2/crispy_forms/tests/test_layout_objects.py 
new/django-crispy-forms-1.8.0/crispy_forms/tests/test_layout_objects.py
--- old/django-crispy-forms-1.7.2/crispy_forms/tests/test_layout_objects.py     
2018-03-09 15:40:03.000000000 +0100
+++ new/django-crispy-forms-1.8.0/crispy_forms/tests/test_layout_objects.py     
2019-10-17 17:14:45.000000000 +0200
@@ -133,6 +133,17 @@
         assert "Introduzca un valor correcto" in html
     deactivate()
 
+def test_remove_labels():
+    form = SampleForm()
+    #remove boolean field as label is still printed in boostrap
+    del form.fields['is_company']
+
+    for fields in form:
+        fields.label = False
+
+    html = render_crispy_form(form)
+
+    assert '<label' not in html
 
 @only_bootstrap
 class TestBootstrapLayoutObjects(object):
@@ -152,7 +163,7 @@
 
         html = render_crispy_form(form)
         if settings.CRISPY_TEMPLATE_PACK == 'bootstrap4':
-            assert 'class="form-check"' in html
+            assert 'class="custom-control-input"' in html
         else:
             assert 'class="radio"' in html
 
@@ -161,7 +172,7 @@
         form.helper.layout = Layout('checkboxes')
         html = render_crispy_form(form)
         if settings.CRISPY_TEMPLATE_PACK == 'bootstrap4':
-            assert 'class="form-check"' in html
+            assert 'class="custom-control-input"' in html
         else:
             assert 'class="checkbox"' in html
 
@@ -225,7 +236,7 @@
         elif settings.CRISPY_TEMPLATE_PACK == 'bootstrap3':
             assert html.count('radio-inline"') == 2
         elif settings.CRISPY_TEMPLATE_PACK == 'bootstrap4':
-            assert html.count('form-check-inline"') == 2
+            assert html.count('custom-control-inline"') == 2
 
     def test_accordion_and_accordiongroup(self, settings):
         test_form = SampleForm()
@@ -249,10 +260,14 @@
             assert html.count('<div class="accordion"') == 1
             assert html.count('<div class="accordion-group">') == 2
             assert html.count('<div class="accordion-heading">') == 2
-        else:
+        elif settings.CRISPY_TEMPLATE_PACK == 'bootstrap3':
             assert html.count('<div class="panel panel-default"') == 2
             assert html.count('<div class="panel-group"') == 1
             assert html.count('<div class="panel-heading">') == 2
+        elif settings.CRISPY_TEMPLATE_PACK == 'bootstrap4':
+            assert html.count('<div id="accordion"') == 1
+            assert html.count('<div class="card mb-2"') == 2
+            assert html.count('<div class="card-header"') == 2
 
         assert html.count('<div id="one"') == 1
         assert html.count('<div id="two"') == 1
@@ -277,11 +292,13 @@
         html = render_crispy_form(test_form)
 
         if settings.CRISPY_TEMPLATE_PACK == 'bootstrap':
-            accordion_class = "accordion-body"
-        else:
-            accordion_class = "panel-collapse"
+            accordion_class = "accordion-body collapse in"
+        elif settings.CRISPY_TEMPLATE_PACK == 'bootstrap3':
+            accordion_class = "panel-collapse collapse in"
+        elif settings.CRISPY_TEMPLATE_PACK == 'bootstrap4':
+            accordion_class = "collapse show"
 
-        assert html.count('<div id="one" class="%s collapse in"' % 
accordion_class) == 1
+        assert html.count('<div id="one" class="%s"' % accordion_class) == 1
 
         test_form.helper.layout = Layout(
             Accordion(
@@ -481,7 +498,7 @@
             if settings.CRISPY_TEMPLATE_PACK == 'bootstrap3':
                 assert html.count('checkbox-inline"') == 3
             elif settings.CRISPY_TEMPLATE_PACK == 'bootstrap4':
-                assert html.count('form-check-inline"') == 3
+                assert html.count('custom-control-inline"') == 3
 
     def test_multiple_checkboxes_unique_ids(self):
         test_form = CheckboxesSampleForm()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-crispy-forms-1.7.2/crispy_forms/tests/test_tags.py 
new/django-crispy-forms-1.8.0/crispy_forms/tests/test_tags.py
--- old/django-crispy-forms-1.7.2/crispy_forms/tests/test_tags.py       
2018-03-05 15:49:56.000000000 +0100
+++ new/django-crispy-forms-1.8.0/crispy_forms/tests/test_tags.py       
2019-10-16 21:06:03.000000000 +0200
@@ -14,6 +14,17 @@
 from .forms import SampleForm
 
 
+def test_crispy_field():
+    template = Template("""
+        {% load crispy_forms_field %}
+        {% for field in form %}
+            {% crispy_field field %}
+        {% endfor %}
+    """)
+    html = template.render(Context({'form': SampleForm()}))
+    assert html.count('<input') == 8
+
+
 def test_as_crispy_errors_form_without_non_field_errors():
     template = Template("""
         {% load crispy_forms_tags %}
@@ -89,7 +100,7 @@
     c = Context({'field': "notafield"})
 
     # Raises an AttributeError when tring to figure out how to render it
-    # Not sure if this is exoected behavior -- @kavdev
+    # Not sure if this is expected behavior -- @kavdev
     error_class = CrispyError if settings.DEBUG else AttributeError
 
     with pytest.raises(error_class):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-crispy-forms-1.7.2/crispy_forms/utils.py 
new/django-crispy-forms-1.8.0/crispy_forms/utils.py
--- old/django-crispy-forms-1.7.2/crispy_forms/utils.py 2017-10-17 
16:10:19.000000000 +0200
+++ new/django-crispy-forms-1.8.0/crispy_forms/utils.py 2019-10-10 
06:46:48.000000000 +0200
@@ -8,10 +8,9 @@
 from django.template import Context
 from django.template.loader import get_template
 from django.utils.functional import SimpleLazyObject
-from django.utils.lru_cache import lru_cache
 
 from .base import KeepContext
-from .compatibility import PY2, text_type
+from .compatibility import PY2, text_type, lru_cache
 
 
 def get_template_pack():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-crispy-forms-1.7.2/django_crispy_forms.egg-info/PKG-INFO 
new/django-crispy-forms-1.8.0/django_crispy_forms.egg-info/PKG-INFO
--- old/django-crispy-forms-1.7.2/django_crispy_forms.egg-info/PKG-INFO 
2018-03-09 15:47:00.000000000 +0100
+++ new/django-crispy-forms-1.8.0/django_crispy_forms.egg-info/PKG-INFO 
2019-10-17 17:25:15.000000000 +0200
@@ -1,12 +1,11 @@
 Metadata-Version: 1.1
 Name: django-crispy-forms
-Version: 1.7.2
+Version: 1.8.0
 Summary: Best way to have Django DRY forms
-Home-page: http://github.com/maraujop/django-crispy-forms
+Home-page: http://github.com/djang-crispy-forms/django-crispy-forms
 Author: Miguel Araujo
 Author-email: [email protected]
 License: MIT
-Description-Content-Type: UNKNOWN
 Description: ===================
         django-crispy-forms
         ===================
@@ -20,17 +19,17 @@
         
         The best way to have Django_ DRY forms. Build programmatic reusable 
layouts out of components, having full control of the rendered HTML without 
writing HTML in templates. All this without breaking the standard way of doing 
things in Django, so it plays nice with any other form application.
         
-        `django-crispy-forms` supports Python 2.7/Python 3.3+ and Django 
1.8/Django 1.10+
+        `django-crispy-forms` supports Python 2.7/Python 3.5+ and Django 1.11, 
2.1, 2.2 and 3.0.
         
         The application mainly provides:
         
         * A filter named ``|crispy`` that will render elegant div based forms. 
Think of it as the built-in methods: ``as_table``, ``as_ul`` and ``as_p``. You 
cannot tune up the output, but it is easy to start using it.
         * A tag named ``{% crispy %}`` that will render a form based on your 
configuration and specific layout setup. This gives you amazing power without 
much hassle, helping you save tons of time.
         
-        Django-crispy-forms supports several frontend frameworks, such as 
Twitter `Bootstrap`_ (versions 2 and 3), `Uni-form`_ and Foundation. You can 
also easily adapt your custom company's one, creating your own, `see the docs`_ 
for more information. You can easily switch among them using 
``CRISPY_TEMPLATE_PACK`` setting variable.
+        Django-crispy-forms supports several frontend frameworks, such as 
Twitter `Bootstrap`_ (versions 2, 3, and 4), `Uni-form`_ and Foundation. You 
can also easily adapt your custom company's one, creating your own, `see the 
docs`_ for more information. You can easily switch among them using 
``CRISPY_TEMPLATE_PACK`` setting variable.
         
         .. _`Uni-form`: http://sprawsm.com/uni-form
-        .. _`Bootstrap`: http://twitter.github.com/bootstrap/index.html
+        .. _`Bootstrap`: https://getbootstrap.com
         .. _`see the docs`: https://django-crispy-forms.readthedocs.io
         
         Authors
@@ -81,14 +80,19 @@
 Classifier: Development Status :: 5 - Production/Stable
 Classifier: Environment :: Web Environment
 Classifier: Framework :: Django
+Classifier: Framework :: Django :: 1.11
+Classifier: Framework :: Django :: 2.1
+Classifier: Framework :: Django :: 2.2
 Classifier: License :: OSI Approved :: MIT License
 Classifier: Operating System :: OS Independent
 Classifier: Programming Language :: JavaScript
+Classifier: Programming Language :: Python :: 2
 Classifier: Programming Language :: Python :: 2.7
-Classifier: Programming Language :: Python :: 3.3
-Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3
 Classifier: Programming Language :: Python :: 3.5
 Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
 Classifier: Topic :: Internet :: WWW/HTTP
 Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
 Classifier: Topic :: Software Development :: Libraries :: Python Modules
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-crispy-forms-1.7.2/django_crispy_forms.egg-info/SOURCES.txt 
new/django-crispy-forms-1.8.0/django_crispy_forms.egg-info/SOURCES.txt
--- old/django-crispy-forms-1.7.2/django_crispy_forms.egg-info/SOURCES.txt      
2018-03-09 15:47:00.000000000 +0100
+++ new/django-crispy-forms-1.8.0/django_crispy_forms.egg-info/SOURCES.txt      
2019-10-17 17:25:15.000000000 +0200
@@ -104,6 +104,7 @@
 crispy_forms/templates/bootstrap4/layout/div.html
 crispy_forms/templates/bootstrap4/layout/field_errors.html
 crispy_forms/templates/bootstrap4/layout/field_errors_block.html
+crispy_forms/templates/bootstrap4/layout/field_file.html
 crispy_forms/templates/bootstrap4/layout/field_with_buttons.html
 crispy_forms/templates/bootstrap4/layout/fieldset.html
 crispy_forms/templates/bootstrap4/layout/formactions.html
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-crispy-forms-1.7.2/setup.cfg 
new/django-crispy-forms-1.8.0/setup.cfg
--- old/django-crispy-forms-1.7.2/setup.cfg     2018-03-09 15:47:00.000000000 
+0100
+++ new/django-crispy-forms-1.8.0/setup.cfg     2019-10-17 17:25:16.000000000 
+0200
@@ -1,7 +1,7 @@
 [metadata]
 license-file = LICENSE.txt
 
-[wheel]
+[bdist_wheel]
 universal = 1
 
 [isort]
@@ -14,6 +14,10 @@
 multi_line_output = 5
 sections = FUTURE,STDLIB,THIRDPARTY,DJANGO,FIRSTPARTY,LOCALFOLDER
 
+[tool:pytest]
+markers = 
+       only: Parametrized mark to limit a test to a single template pack
+
 [coverage:run]
 branch = True
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-crispy-forms-1.7.2/setup.py 
new/django-crispy-forms-1.8.0/setup.py
--- old/django-crispy-forms-1.7.2/setup.py      2017-10-17 16:10:19.000000000 
+0200
+++ new/django-crispy-forms-1.8.0/setup.py      2019-10-17 17:24:14.000000000 
+0200
@@ -28,14 +28,20 @@
         "Development Status :: 5 - Production/Stable",
         "Environment :: Web Environment",
         "Framework :: Django",
+        "Framework :: Django :: 1.11",
+        "Framework :: Django :: 2.1",
+        "Framework :: Django :: 2.2",
+#        "Framework :: Django :: 3.0",
         "License :: OSI Approved :: MIT License",
         "Operating System :: OS Independent",
         "Programming Language :: JavaScript",
+        "Programming Language :: Python :: 2",
         "Programming Language :: Python :: 2.7",
-        "Programming Language :: Python :: 3.3",
-        "Programming Language :: Python :: 3.4",
+        "Programming Language :: Python :: 3",
         "Programming Language :: Python :: 3.5",
         "Programming Language :: Python :: 3.6",
+        "Programming Language :: Python :: 3.7",
+        "Programming Language :: Python :: 3.8",
         "Topic :: Internet :: WWW/HTTP",
         "Topic :: Internet :: WWW/HTTP :: Dynamic Content",
         "Topic :: Software Development :: Libraries :: Python Modules",
@@ -43,7 +49,7 @@
     keywords=['forms', 'django', 'crispy', 'DRY'],
     author='Miguel Araujo',
     author_email='[email protected]',
-    url='http://github.com/maraujop/django-crispy-forms',
+    url='http://github.com/djang-crispy-forms/django-crispy-forms',
     license='MIT',
     packages=find_packages(exclude=['docs']),
     include_package_data=True,


Reply via email to