From 30f9d5ffb5268e3f5898579f73d8c725a0fc4741 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20T=C4=99=C5=BCycki?= Date: Tue, 7 Mar 2017 23:19:15 +0100 Subject: [PATCH] This fix issue #1 --- .travis.yml | 70 +++++++------- CHANGELOG.md | 20 ++-- django_popup_view_field/__init__.py | 2 +- .../popup_view_widget.html | 29 ++++++ django_popup_view_field/tests/test_views.py | 2 - django_popup_view_field/widgets.py | 91 +++++++++++-------- requirements-dev.txt | 2 +- tox.ini | 20 ++-- 8 files changed, 144 insertions(+), 92 deletions(-) create mode 100644 django_popup_view_field/templates/django_popup_view_field/popup_view_widget.html diff --git a/.travis.yml b/.travis.yml index 0150728..354819d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,37 +1,43 @@ sudo: false language: python -env: - - TOXENV=py27-dj_1.8-bootstrap_7.0.0-crispy_1.5.0-tests - - TOXENV=py27-dj_1.8-bootstrap_7.0.0-crispy_1.5.1-tests - - TOXENV=py34-dj_1.8-bootstrap_7.0.0-crispy_1.5.0-tests - - TOXENV=py34-dj_1.8-bootstrap_7.0.0-crispy_1.5.1-tests - - TOXENV=py27-dj_1.9-bootstrap_7.1.0-crispy_1.6.0-tests - - TOXENV=py27-dj_1.9-bootstrap_7.1.0-crispy_1.6.1-tests - - TOXENV=py27-dj_1.9-bootstrap_7.0.0-crispy_1.6.0-tests - - TOXENV=py27-dj_1.9-bootstrap_7.0.0-crispy_1.6.1-tests - - TOXENV=py27-dj_1.9-bootstrap_8.1.0-crispy_1.6.0-tests - - TOXENV=py27-dj_1.9-bootstrap_8.1.0-crispy_1.6.1-tests - - TOXENV=py34-dj_1.9-bootstrap_7.1.0-crispy_1.6.0-tests - - TOXENV=py34-dj_1.9-bootstrap_7.1.0-crispy_1.6.1-tests - - TOXENV=py34-dj_1.9-bootstrap_7.0.0-crispy_1.6.0-tests - - TOXENV=py34-dj_1.9-bootstrap_7.0.0-crispy_1.6.1-tests - - TOXENV=py34-dj_1.9-bootstrap_8.1.0-crispy_1.6.0-tests - - TOXENV=py34-dj_1.9-bootstrap_8.1.0-crispy_1.6.1-tests - - TOXENV=py27-dj_1.10-bootstrap_7.1.0-crispy_1.6.1-tests - - TOXENV=py27-dj_1.10-bootstrap_7.1.0-crispy_1.6.1-tests - - TOXENV=py27-dj_1.10-bootstrap_7.0.0-crispy_1.6.1-tests - - TOXENV=py27-dj_1.10-bootstrap_7.0.0-crispy_1.6.1-tests - - TOXENV=py27-dj_1.10-bootstrap_8.1.0-crispy_1.6.1-tests - - TOXENV=py27-dj_1.10-bootstrap_8.1.0-crispy_1.6.1-tests - - TOXENV=py34-dj_1.10-bootstrap_7.1.0-crispy_1.6.1-tests - - TOXENV=py34-dj_1.10-bootstrap_7.1.0-crispy_1.6.1-tests - - TOXENV=py34-dj_1.10-bootstrap_7.0.0-crispy_1.6.1-tests - - TOXENV=py34-dj_1.10-bootstrap_7.0.0-crispy_1.6.1-tests - - TOXENV=py34-dj_1.10-bootstrap_8.1.0-crispy_1.6.1-tests - - TOXENV=py34-dj_1.10-bootstrap_8.1.0-crispy_1.6.1-tests - - TOXENV=py27-flake - - TOXENV=py34-flake - - TOXENV=py34-isort + +matrix: + include: + - { python: 2.7, env: TOXENV=py27-dj_1.8-bootstrap_7.1-crispy_1.5-tests } + - { python: 3.4, env: TOXENV=py34-dj_1.8-bootstrap_7.1-crispy_1.5-tests } + - { python: 2.7, env: TOXENV=py27-dj_1.9-bootstrap_7.1-crispy_1.5-tests } + - { python: 2.7, env: TOXENV=py27-dj_1.9-bootstrap_7.1-crispy_1.6-tests } + - { python: 2.7, env: TOXENV=py27-dj_1.9-bootstrap_8.1-crispy_1.5-tests } + - { python: 2.7, env: TOXENV=py27-dj_1.9-bootstrap_8.1-crispy_1.6-tests } + - { python: 2.7, env: TOXENV=py27-dj_1.9-bootstrap_8.2-crispy_1.5-tests } + - { python: 2.7, env: TOXENV=py27-dj_1.9-bootstrap_8.2-crispy_1.6-tests } + - { python: 3.4, env: TOXENV=py34-dj_1.9-bootstrap_7.1-crispy_1.5-tests } + - { python: 3.4, env: TOXENV=py34-dj_1.9-bootstrap_7.1-crispy_1.6-tests } + - { python: 3.4, env: TOXENV=py34-dj_1.9-bootstrap_8.1-crispy_1.5-tests } + - { python: 3.4, env: TOXENV=py34-dj_1.9-bootstrap_8.1-crispy_1.6-tests } + - { python: 3.4, env: TOXENV=py34-dj_1.9-bootstrap_8.2-crispy_1.5-tests } + - { python: 3.4, env: TOXENV=py34-dj_1.9-bootstrap_8.2-crispy_1.6-tests } + - { python: 2.7, env: TOXENV=py27-dj_1.10-bootstrap_7.1-crispy_1.5-tests } + - { python: 2.7, env: TOXENV=py27-dj_1.10-bootstrap_7.1-crispy_1.6-tests } + - { python: 2.7, env: TOXENV=py27-dj_1.10-bootstrap_8.1-crispy_1.5-tests } + - { python: 2.7, env: TOXENV=py27-dj_1.10-bootstrap_8.1-crispy_1.6-tests } + - { python: 2.7, env: TOXENV=py27-dj_1.10-bootstrap_8.2-crispy_1.5-tests } + - { python: 2.7, env: TOXENV=py27-dj_1.10-bootstrap_8.2-crispy_1.6-tests } + - { python: 3.4, env: TOXENV=py34-dj_1.10-bootstrap_7.1-crispy_1.5-tests } + - { python: 3.4, env: TOXENV=py34-dj_1.10-bootstrap_7.1-crispy_1.6-tests } + - { python: 3.4, env: TOXENV=py34-dj_1.10-bootstrap_8.1-crispy_1.5-tests } + - { python: 3.4, env: TOXENV=py34-dj_1.10-bootstrap_8.1-crispy_1.6-tests } + - { python: 3.4, env: TOXENV=py34-dj_1.10-bootstrap_8.2-crispy_1.5-tests } + - { python: 3.4, env: TOXENV=py34-dj_1.10-bootstrap_8.2-crispy_1.6-tests } + - { python: 2.7, env: TOXENV=py27-dj_1.11-bootstrap_8.2-crispy_1.6-tests } + - { python: 3.4, env: TOXENV=py34-dj_1.11-bootstrap_8.2-crispy_1.6-tests } + - { python: 2.7, env: TOXENV=py27-flake } + - { python: 3.4, env: TOXENV=py34-flake } + - { python: 3.4, env: TOXENV=py34-isort } + + allow_failures: + - env: TOXENV=py27-dj_1.11-bootstrap_8.2-crispy_1.6-tests + - env: TOXENV=py34-dj_1.11-bootstrap_8.2-crispy_1.6-tests install: - pip install tox>=2.5.0 diff --git a/CHANGELOG.md b/CHANGELOG.md index 01432af..3f6bc93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,20 +1,24 @@ # CHANGELOG for django-popup-view-field +## 0.3.0 (2017-03-07) + +* Support for Django 1.11 + ## 0.2.0 (2017-02-20) - * Remove PopupViewField from django_popup_view_field.__init__, - now you must import PopupViewField from django_popup_view_field.fields +* Remove PopupViewField from django_popup_view_field.__init__, + now you must import PopupViewField from django_popup_view_field.fields - * Sorting imports using isort +* Sorting imports using isort - * Checking the order of imports in the tox +* Checking the order of imports in the tox - * Checking support for django-bootstrap3 v8.1.0 +* Checking support for django-bootstrap3 v8.1.0 - * Added django-bootstrap3 v8.1.0 to tox +* Added django-bootstrap3 v8.1.0 to tox - * Adding version in django_popup_view_field.__init__ +* Adding version in django_popup_view_field.__init__ ## 0.1 (2016-12-27) - * Initial version + tests + Travis CI +* Initial version + tests + Travis CI diff --git a/django_popup_view_field/__init__.py b/django_popup_view_field/__init__.py index f295503..65a0704 100644 --- a/django_popup_view_field/__init__.py +++ b/django_popup_view_field/__init__.py @@ -1,2 +1,2 @@ -VERSION = (0, 2, 0) +VERSION = (0, 3, 0) __version__ = ".".join(str(i) for i in VERSION) diff --git a/django_popup_view_field/templates/django_popup_view_field/popup_view_widget.html b/django_popup_view_field/templates/django_popup_view_field/popup_view_widget.html new file mode 100644 index 0000000..3704e22 --- /dev/null +++ b/django_popup_view_field/templates/django_popup_view_field/popup_view_widget.html @@ -0,0 +1,29 @@ +{% spaceless %} +
+ + + + + +
+{% endspaceless %} diff --git a/django_popup_view_field/tests/test_views.py b/django_popup_view_field/tests/test_views.py index 29cdb00..260877f 100644 --- a/django_popup_view_field/tests/test_views.py +++ b/django_popup_view_field/tests/test_views.py @@ -29,8 +29,6 @@ def test_status(self): def test_get_response(self): response = self.client.get(self.url) html = response.content.decode("utf-8") - # print("*******************") - # print(html) self.assertTrue(response.context['form'] is not None) self.assertInHTML("View 1", html) assert html.find('''class="input-group-addon btn popup-view-btn-load"''') != -1 diff --git a/django_popup_view_field/widgets.py b/django_popup_view_field/widgets.py index 4b0d2a6..25deab7 100644 --- a/django_popup_view_field/widgets.py +++ b/django_popup_view_field/widgets.py @@ -1,6 +1,8 @@ +import django from django import forms from django.core.urlresolvers import reverse from django.forms.utils import flatatt +from django.template import loader from django.utils.encoding import force_text from django.utils.html import format_html @@ -9,13 +11,21 @@ class PopupViewWidget(forms.TextInput): """ Widget is compatible with crispy forms and django-bootstrap3 Render input field with two buttons: - first button for clear field - second button for call popup dialog + first button for clean field + second button to call popup dialog """ + template_name = 'django_popup_view_field/popup_view_widget.html' + def __init__(self, view_class_name, popup_dialog_title, attrs=None): self.view_class_name = view_class_name self.popup_dialog_title = popup_dialog_title + + # compability for Django v1.11 + if attrs is not None: + self.attrs = attrs.copy() + else: + self.attrs = {} super(PopupViewWidget, self).__init__(attrs=attrs) def get_view_url(self): @@ -23,44 +33,49 @@ def get_view_url(self): url = reverse("django_popup_view_field:get_popup_view", args=(self.view_class_name,)) return url - def render(self, name, value, attrs=None): - if value is None: - value = '' + def get_context(self, name, value, attrs=None): + + # For Django >= 1.11 + try: + context = super(PopupViewWidget, self).get_context(name, value, attrs) + + # For Django < 1.11 + except AttributeError: + attrs = self.build_attrs(attrs) + context = { + 'widget': { + 'name': name, + 'is_hidden': self.is_hidden, + 'type': self.input_type, + 'attrs': self.build_attrs(attrs), + 'template_name': self.template_name + } + } + + # Only add the 'value' attribute if a value is non-empty. + # This code come from django + if value != '': + context['widget']['value'] = force_text(self._format_value(value)) - final_attrs = self.build_attrs(attrs, type=self.input_type, name=name) + # Extra attrs for popup + context['widget']['popup_dialog_title'] = self.popup_dialog_title + context['widget']['url'] = self.get_view_url() # Add to input css class 'form-control' - css_class = final_attrs.get("class", "").split() + css_class = context['widget']['attrs'].get("class", "").split() if "form-control" not in css_class: css_class.append("form-control") - css_class = " ".join(css_class) - final_attrs['class'] = css_class - - if value != '': - final_attrs['value'] = force_text(self._format_value(value)) - - html = ''' -
- - - - - -
- '''.format( - attrs=flatatt(final_attrs), # Default attrs for text input - target_input_id=final_attrs.get("id", ""), # id target - place where value from dialog will be insert - popup_dialog_title=self.popup_dialog_title, # title for dialog - url=self.get_view_url() - ) - - return format_html(html) + context['widget']['attrs']['class'] = " ".join(set(css_class)) + + return context + + def render(self, name, value, attrs=None, **kwargs): + value = value or '' + context = self.get_context(name, value, attrs) + + if django.VERSION < (1, 11): + template = loader.get_template(self.template_name) + return template.render(context).strip() + + else: + return super(PopupViewWidget, self).render(name, value, attrs, **kwargs) diff --git a/requirements-dev.txt b/requirements-dev.txt index 7fb55c5..2fe2bf7 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,4 +1,4 @@ -Django==1.10.5 +Django==1.11b1 tox>=2.5.0 django-bootstrap3 django-crispy-forms diff --git a/tox.ini b/tox.ini index 333c48e..1c789be 100644 --- a/tox.ini +++ b/tox.ini @@ -1,9 +1,10 @@ [tox] minversion = 1.8 envlist= - {py27,py34}-dj_1.8-bootstrap_7.0.0-crispy_{1.5.0,1.5.1}-tests, - {py27,py34}-dj_1.9-bootstrap_{7.1.0,7.0.0,8.1.0}-crispy_{1.6.0,1.6.1}-tests, - {py27,py34}-dj_1.10-bootstrap_{7.1.0,7.0.0,8.1.0}-crispy_{1.6.1,1.6.1}-tests, + {py27,py34}-dj_1.8-bootstrap_7.1-crispy_1.5-tests, + {py27,py34}-dj_1.9-bootstrap_{7.1,8.1,8.2}-crispy_{1.5,1.6}-tests, + {py27,py34}-dj_1.10-bootstrap_{7.1,8.1,8.2}-crispy_{1.5,1.6}-tests, + {py27,py34}-dj_1.11-bootstrap_{8.2}-crispy_{1.6}-tests, {py27,py34}-flake, py34-isort @@ -20,13 +21,12 @@ deps = dj_1.8: Django>=1.8,<1.9 dj_1.9: Django>=1.9,<1.10 dj_1.10: Django>=1.9,<1.11 - crispy_1.5.0: django-crispy-forms==1.5.0 - crispy_1.5.1: django-crispy-forms==1.5.1 - crispy_1.6.0: django-crispy-forms==1.6.0 - crispy_1.6.1: django-crispy-forms==1.6.1 - bootstrap_7.0.0: django-bootstrap3==7.0.0 - bootstrap_7.1.0: django-bootstrap3==7.1.0 - bootstrap_8.1.0: django-bootstrap3==8.1.0 + dj_1.11: Django==1.11b1 + crispy_1.5: django-crispy-forms==1.5.1 + crispy_1.6: django-crispy-forms==1.6.1 + bootstrap_7.1: django-bootstrap3==7.1.0 + bootstrap_8.1: django-bootstrap3==8.1.0 + bootstrap_8.2: django-bootstrap3==8.2.1 commands = tests: ./run_test.py