Compare commits

...
4 Commits
Author SHA1 Message Date
Johannes Hoppe 4defb8112b Fixed #222 -- Display intital data for heavy widgets 2015-12-01 10:19:02 +01:00
Johannes Hoppe bb90be77b7 Fixed #231 -- Avoid fetching entire queryset from db
Patched ciritcal memory leak in ModelSelect2 widgets.
Boolean evaluation of queryset makes django fetch all
elements.

Thanks to @magicjohnson for discovering this issue
2015-11-30 13:17:02 +01:00
Johannes Hoppe 18647161a1 Fixed docs 2015-11-29 20:47:22 +01:00
Royendgel Silberie 3e6c1fc3ba fixing small typo
Closed #227
2015-11-29 20:03:01 +01:00
5 changed files with 34 additions and 8 deletions
+6
View File
@@ -1,6 +1,12 @@
Changelog Summary
=================
### v5.4.2
* Fixed initial data not being shown for heavy widgets.
### v5.4.1
* Fixed memory leak in `ModelSelect2Mixin` and subclasses
### v5.4.0
* Added `Select2TagWidget` a light widget with tagging support
+1 -1
View File
@@ -9,4 +9,4 @@ The app includes Select2 driven Django Widgets and Form Fields.
"""
__version__ = "5.4.0"
__version__ = "5.4.2"
+8 -3
View File
@@ -49,6 +49,7 @@ Light widgets are normally named, i.e. there is no
from __future__ import absolute_import, unicode_literals
from functools import reduce
from itertools import chain
from django import forms
from django.core import signing
@@ -233,6 +234,7 @@ class HeavySelect2Mixin(Select2Mixin):
def render_options(self, choices, selected_choices):
"""Render only selected options."""
choices = chain(choices, self.choices)
output = ['<option></option>' if not self.is_required else '']
choices = {(k, v) for k, v in choices if k in selected_choices}
selected_choices = {force_text(v) for v in selected_choices}
@@ -274,6 +276,8 @@ class HeavySelect2MultipleWidget(HeavySelect2Mixin, forms.SelectMultiple):
class HeavySelect2TagWidget(Select2TagMixin, HeavySelect2MultipleWidget):
"""Select2 tag widget."""
pass
@@ -349,7 +353,7 @@ class ModelSelect2Mixin(object):
:return: Filtered queryset
:rtype: :class:`.django.db.models.QuerySet`
"""
if not queryset:
if queryset is None:
queryset = self.get_queryset()
search_fields = self.get_search_fields()
select = Q()
@@ -398,6 +402,7 @@ class ModelSelect2Mixin(object):
choices = {self.choices.choice(obj)
for obj in self.choices.queryset.filter(pk__in=selected_choices)}
else:
choices = chain(choices, self.choices)
choices = {(k, v) for k, v in choices if k in selected_choices}
selected_choices = {force_text(v) for v in selected_choices}
for option_value, option_label in choices:
@@ -414,7 +419,7 @@ class ModelSelect2Widget(ModelSelect2Mixin, HeavySelect2Widget):
class MyWidget(ModelSelect2Widget):
search_fields = [
'title__icontians',
'title__icontains',
]
class MyModelForm(forms.ModelForm):
@@ -458,7 +463,7 @@ class ModelSelect2MultipleWidget(ModelSelect2Mixin, HeavySelect2MultipleWidget):
class ModelSelect2TagWidget(Select2TagMixin, ModelSelect2MultipleWidget):
"""
Select2 model field with tag support.
Select2 model widget with tag support.
This it not a simple drop in widget.
It requires to implement you own :func:`.value_from_datadict`
+14 -1
View File
@@ -30,6 +30,11 @@ class TestSelect2Mixin(object):
form = forms.AlbumSelect2WidgetForm()
widget_cls = Select2Widget
def test_initial_data(self, genres):
genre = genres[0]
form = self.form.__class__(initial={'primary_genre': genre.pk})
assert text_type(genre) in form.as_p()
def test_initial_form_class(self):
widget = self.widget_cls(attrs={'class': 'my-class'})
assert 'my-class' in widget.render('name', None)
@@ -81,9 +86,12 @@ class TestSelect2Mixin(object):
class TestHeavySelect2Mixin(TestSelect2Mixin):
url = reverse('heavy_select2_widget')
form = forms.HeavySelect2WidgetForm(initial={'primary_genre': [1]})
form = forms.HeavySelect2WidgetForm(initial={'primary_genre': 1})
widget_cls = HeavySelect2Widget
def test_initial_data(self):
assert 'One' in self.form.as_p()
def test_initial_form_class(self):
widget = self.widget_cls(data_view='heavy_data_1', attrs={'class': 'my-class'})
assert 'my-class' in widget.render('name', None)
@@ -129,6 +137,11 @@ class TestHeavySelect2Mixin(TestSelect2Mixin):
class TestModelSelect2Mixin(TestHeavySelect2Mixin):
form = forms.AlbumModelSelect2WidgetForm(initial={'primary_genre': 1})
def test_initial_data(self, genres):
genre = genres[0]
form = self.form.__class__(initial={'primary_genre': genre.pk})
assert text_type(genre) in form.as_p()
@pytest.fixture(autouse=True)
def genres(self, db):
return mommy.make(Genre, 100)
+5 -3
View File
@@ -114,11 +114,13 @@ class Select2WidgetForm(forms.Form):
class HeavySelect2WidgetForm(forms.Form):
artist = forms.ChoiceField(
widget=HeavySelect2Widget(data_view='heavy_data_1', choices=NUMBER_CHOICES)
widget=HeavySelect2Widget(data_view='heavy_data_1'),
choices=NUMBER_CHOICES
)
primary_genre = forms.ChoiceField(
widget=HeavySelect2Widget(data_view='heavy_data_2', choices=NUMBER_CHOICES),
required=False
widget=HeavySelect2Widget(data_view='heavy_data_2'),
required=False,
choices=NUMBER_CHOICES
)