Skip to content

Commit db22be6

Browse files
committed
Added ModelSelect2Mixin.result_from_instance() method.
1 parent 5e1ba19 commit db22be6

File tree

5 files changed

+62
-2
lines changed

5 files changed

+62
-2
lines changed

django_select2/forms.py

+19
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,25 @@ def label_from_instance(obj):
554554
"""
555555
return str(obj)
556556

557+
def result_from_instance(self, obj):
558+
"""
559+
Return a dictionary representing the object.
560+
561+
Can be overridden to change the result returned by
562+
:class:`.AutoResponseView` for each object.
563+
564+
Example usage::
565+
566+
class MyWidget(ModelSelect2Widget):
567+
def result_from_instance(obj):
568+
return {
569+
'id': obj.pk,
570+
'text': self.label_from_instance(obj),
571+
'extra_data': obj.extra_data,
572+
}
573+
"""
574+
return {"id": obj.pk, "text": self.label_from_instance(obj)}
575+
557576

558577
class ModelSelect2Widget(ModelSelect2Mixin, HeavySelect2Widget):
559578
"""

django_select2/views.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ def get(self, request, *args, **kwargs):
2121
"""
2222
Return a :class:`.django.http.JsonResponse`.
2323
24+
Each result will be rendered by the widget's
25+
:func:`django_select2.forms.ModelSelect2Mixin.result_from_instance` method.
26+
2427
Example::
2528
2629
{
@@ -41,7 +44,7 @@ def get(self, request, *args, **kwargs):
4144
return JsonResponse(
4245
{
4346
"results": [
44-
{"text": self.widget.label_from_instance(obj), "id": obj.pk}
47+
self.widget.result_from_instance(obj)
4548
for obj in context["object_list"]
4649
],
4750
"more": context["page_obj"].has_next(),

tests/test_forms.py

+8
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,14 @@ def test_get_queryset(self):
438438
widget.queryset = Genre.objects.all()
439439
assert isinstance(widget.get_queryset(), QuerySet)
440440

441+
def test_result_from_instance_ModelSelect2Widget(self, genres):
442+
widget = ModelSelect2Widget()
443+
widget.model = Genre
444+
genre = Genre.objects.first()
445+
assert widget.result_from_instance(genre) == {
446+
'id': genre.pk, 'text': str(genre)
447+
}
448+
441449
def test_tag_attrs_Select2Widget(self):
442450
widget = Select2Widget()
443451
output = widget.render("name", "value")

tests/test_views.py

+17-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44

55
from django_select2.cache import cache
66
from django_select2.forms import ModelSelect2Widget
7-
from tests.testapp.forms import AlbumModelSelect2WidgetForm, ArtistCustomTitleWidget
7+
from tests.testapp.forms import (
8+
AlbumModelSelect2WidgetForm, ArtistCustomTitleWidget, CityForm
9+
)
810
from tests.testapp.models import Genre
911

1012
try:
@@ -84,6 +86,20 @@ def test_label_from_instance(self, artists, client):
8486
"results"
8587
]
8688

89+
def test_result_from_instance(self, cities, client):
90+
url = reverse("django_select2:auto-json")
91+
92+
form = CityForm()
93+
assert form.as_p()
94+
field_id = form.fields["city"].widget.field_id
95+
city = cities[0]
96+
response = client.get(url, {"field_id": field_id, "term": city.name})
97+
assert response.status_code == 200
98+
data = json.loads(response.content.decode("utf-8"))
99+
assert data["results"]
100+
assert {"id": city.pk, "text": smart_str(city),
101+
"country": smart_str(city.country)} in data["results"]
102+
87103
def test_url_check(self, client, artists):
88104
artist = artists[0]
89105
form = AlbumModelSelect2WidgetForm()

tests/testapp/forms.py

+14
Original file line numberDiff line numberDiff line change
@@ -232,3 +232,17 @@ class Meta:
232232
model = models.Groupie
233233
fields = "__all__"
234234
widgets = {"obsession": ArtistCustomTitleWidget}
235+
236+
237+
class CityModelSelect2Widget(ModelSelect2Widget):
238+
model = City
239+
search_fields = ["name"]
240+
241+
def result_from_instance(self, obj):
242+
return {"id": obj.pk, "text": obj.name, "country": str(obj.country)}
243+
244+
245+
class CityForm(forms.Form):
246+
city = forms.ModelChoiceField(
247+
queryset=City.objects.all(), widget=CityModelSelect2Widget(), required=False
248+
)

0 commit comments

Comments
 (0)