hello, I'm moving to DAL v3. I wonder if it is possible that the value set to form the initial, is shown as get_result_label
Sample code
from django.views import generic
from django.db.models import Q
from django.core.urlresolvers import reverse_lazy
from django.contrib.auth.models import User
from dal import autocomplete
from .models import SampleModel
from .forms import SampleForm
class UserAutocomplete(autocomplete.Select2QuerySetView):
def get_queryset(self):
# Don't forget to filter out results depending on the visitor !
if not self.request.user.is_authenticated():
return User.objects.none()
qs = User.objects.all()
if self.q:
qs = qs.filter(Q(first_name__icontains=self.q) | Q(last_name__icontains=self.q))
return qs
def get_result_label(self, result):
return result.get_full_name().title()
class SampleView(generic.UpdateView):
form_class = SampleForm
model = SampleModel
def get_success_url(self):
return reverse_lazy('sample_update', {'pk': self.object.pk})
def get_initial(self):
initial = super(SampleView, self).get_initial()
user = getattr(self.request, 'user', None)
if user and user.is_authenticated():
initial.update({'selected_user': user})
return initial
from django.db import models
from django.contrib.auth.models import User
class SampleModel(models.Model):
selected_user = models.ForeignKey(to=User,
related_name="%(app_label)s_%(class)s_selected_user", null=True,
blank=True, on_delete=models.SET_NULL)
from dal import autocomplete
from django import forms
from django.contrib.auth.models import User
from .models import SampleModel
class SampleForm(forms.ModelForm):
selected_user = forms.ModelChoiceField(
queryset=User.objects.all(),
widget=autocomplete.ModelSelect2(url='user-autocomplete')
)
class Meta:
models = SampleModel
fields = '__all__'
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^sample-update/(?P<pk>\d+)/$',
views.SampleView.as_view(),
name='sample_update'
),
url(r'^user-autocomplete/$',
views.UserAutocomplete.as_view(),
name='user-autocomplete'
)
]
This is not a problem DAL v3.
it was necessary to create a new class that inherits from forms.ModelChoiceField and create a label_from_instance method which returns the value of the label that need.
look at the end of the ModelChoiceField documentation https://docs.djangoproject.com/es/1.9/ref/forms/fields/#modelchoicefield
this would be a good example to include in the documentation, because I believe it is a common use.
from dal import autocomplete
from django import forms
from django.contrib.auth.models import User
from .models import SampleModel
class UserModelChoiceField(forms.ModelChoiceField):
def label_from_instance(self, obj):
return obj.get_full_name().title()
class SampleForm(forms.ModelForm):
selected_user = UserModelChoiceField(
queryset=User.objects.all(),
widget=autocomplete.ModelSelect2(url='user-autocomplete')
)
class Meta:
models = SampleModel
fields = '__all__'
@jpic thank you for the incredible work.
This would be pretty cool to add to the docs indeed​ !
Solution is in the docs: https://select2.org/programmatic-control/add-select-clear-items#preselecting-options-in-an-remotely-sourced-ajax-select2
It would be nice to have generic view for this case. At the moment it an be solved like this:
let page_selects = $(
'.nested-list-form [data-autocomplete-light-function=select2]',
)
page_selects.each(function() {
let select = $(this)
$.ajax({
type: 'GET',
url: select.data('autocompleteLightUrl'),
data: {
forward: JSON.stringify({
id: select.val(),
}),
},
}).then(function(data) {
// create the option and append to Select2
let option = new Option(
data.results[0].selected_text,
data.results[0].id,
true,
true,
)
select.append(option).trigger('change')
// manually trigger the `select2:select` event
select.trigger({
type: 'select2:select',
params: {
data: data,
},
})
})
})
at your view:
def get_queryset(self):
# ....
# Exclude anything but specific item
page_id = self.forwarded.get("id")
if page_id:
qs = qs.filter(pk=page_id)
if self.q:
qs = qs.search(self.q, fields=[self.model_field_name])
return qs
get_result_label and get_selected_result_label stays as is.
Great solution by @pySilver! Works perfect! Would be great to have it in standard library!
@Simanas it should be a little bit different:
// @see: https://github.com/yourlabs/django-autocomplete-light/issues/607#issuecomment-570440273
;(function($) {
'use strict'
window.addEventListener('dal-function-registered.select2', function() {
$(function() {
$('select[data-autocomplete-light-function=select2]')
.filter('select[data-autocomplete-light-url]')
.each(function(i, obj) {
let select = $(this)
if (!select.data('autocompleteLightUrl')) {
return
}
let val = select.val()
if ($.isEmptyObject(val)) {
return
}
let forward = yl.getForwards(select)
if (forward === undefined) {
return
}
forward = JSON.parse(forward)
forward['id'] = select.val()
forward = JSON.stringify(forward)
$.ajax({
type: 'GET',
url: select.data('autocompleteLightUrl'),
data: {
forward: forward,
},
}).then(function(data) {
// create the option and append to Select2
select.empty()
for (let i = 0; i < data.results.length; i++) {
let option = new Option(
data.results[i].selected_text,
data.results[i].id,
true,
true,
)
select.append(option).trigger('change')
}
// manually trigger the `select2:select` event
select.trigger({
type: 'select2:select',
params: {
data: data,
},
})
})
})
})
})
})(jQuery)
What is yl.getForwards(select)?
Most helpful comment
RESOLVED!!
This is not a problem DAL v3.
it was necessary to create a new class that inherits from
forms.ModelChoiceFieldand create alabel_from_instancemethod which returns the value of the label that need.look at the end of the ModelChoiceField documentation https://docs.djangoproject.com/es/1.9/ref/forms/fields/#modelchoicefield
this would be a good example to include in the documentation, because I believe it is a common use.
@jpic thank you for the incredible work.