mirror of
https://github.com/Hopiu/django-select2.git
synced 2026-05-21 11:11:52 +00:00
Add support for custom to_field names for foreign keys (#486)
Django's ForeignKey supports custom to_fields. The to field is the primary key by default, but can be modified. The to field is also used by forms to reduce database lookups. This patch add support for custom to_field names on both model or form layer.
This commit is contained in:
parent
496cc7c502
commit
f31beec0c4
4 changed files with 27 additions and 7 deletions
|
|
@ -444,11 +444,12 @@ class ModelSelect2Mixin(object):
|
||||||
c for c in selected_choices
|
c for c in selected_choices
|
||||||
if c not in self.choices.field.empty_values
|
if c not in self.choices.field.empty_values
|
||||||
}
|
}
|
||||||
choices = (
|
field_name = self.choices.field.to_field_name or 'pk'
|
||||||
(obj.pk, self.label_from_instance(obj))
|
query = Q(**{'%s__in' % field_name: selected_choices})
|
||||||
for obj in self.choices.queryset.filter(pk__in=selected_choices)
|
for obj in self.choices.queryset.filter(query):
|
||||||
)
|
option_value = self.choices.choice(obj)[0]
|
||||||
for option_value, option_label in choices:
|
option_label = self.label_from_instance(obj)
|
||||||
|
|
||||||
selected = (
|
selected = (
|
||||||
str(option_value) in value and
|
str(option_value) in value and
|
||||||
(has_selected is False or self.allow_multiple_selected)
|
(has_selected is False or self.allow_multiple_selected)
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ from tests.testapp import forms
|
||||||
from tests.testapp.forms import (
|
from tests.testapp.forms import (
|
||||||
NUMBER_CHOICES, HeavySelect2MultipleWidgetForm, TitleModelSelect2Widget
|
NUMBER_CHOICES, HeavySelect2MultipleWidgetForm, TitleModelSelect2Widget
|
||||||
)
|
)
|
||||||
from tests.testapp.models import City, Country, Genre
|
from tests.testapp.models import Artist, City, Country, Genre, Groupie
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
|
@ -362,6 +362,12 @@ class TestModelSelect2Mixin(TestHeavySelect2Mixin):
|
||||||
widget = ModelSelect2Widget(queryset=Genre.objects.all(), search_fields=['title__icontains'])
|
widget = ModelSelect2Widget(queryset=Genre.objects.all(), search_fields=['title__icontains'])
|
||||||
assert isinstance(widget.get_url(), text_type)
|
assert isinstance(widget.get_url(), text_type)
|
||||||
|
|
||||||
|
def test_custom_to_field_name(self):
|
||||||
|
the_best_band_in_the_world = Artist.objects.create(title='Take That')
|
||||||
|
groupie = Groupie.objects.create(obsession=the_best_band_in_the_world)
|
||||||
|
form = forms.GroupieForm(instance=groupie)
|
||||||
|
assert '<option value="Take That" selected>TAKE THAT</option>' in form.as_p()
|
||||||
|
|
||||||
|
|
||||||
class TestHeavySelect2TagWidget(TestHeavySelect2Mixin):
|
class TestHeavySelect2TagWidget(TestHeavySelect2Mixin):
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -195,3 +195,12 @@ class AddressChainedSelect2WidgetForm(forms.Form):
|
||||||
max_results=500,
|
max_results=500,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class GroupieForm(forms.ModelForm):
|
||||||
|
class Meta:
|
||||||
|
model = models.Groupie
|
||||||
|
fields = '__all__'
|
||||||
|
widgets = {
|
||||||
|
'obsession': ArtistCustomTitleWidget
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ class Genre(models.Model):
|
||||||
|
|
||||||
|
|
||||||
class Artist(models.Model):
|
class Artist(models.Model):
|
||||||
title = models.CharField(max_length=50)
|
title = models.CharField(max_length=50, unique=True)
|
||||||
genres = models.ManyToManyField(Genre)
|
genres = models.ManyToManyField(Genre)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
@ -56,3 +56,7 @@ class City(models.Model):
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
|
||||||
|
class Groupie(models.Model):
|
||||||
|
obsession = models.ForeignKey(Artist, to_field='title', on_delete=models.CASCADE)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue