Closed nikolaysm closed 4 years ago
Hi @nikolaysm,
Thanks for reaching out. I am not 100% certain I understood your problem, but I am just going to guess. Let me know if my guess is wrong and please provide me with more detail about your problem, rather than your current shot at a solution.
So my guess is, you are trying to display different options depending on the authenticated user, correct?
If so all you need to do is to override the filter_queryset method. The first argument the method gets is the current request and the second is the search term for that request. In other words whatever the user is currently typing into the Select2 search field.
So a solution could look similar to something like this:
from django_select2.forms import ModelSelect2Widget
class MyWidget(ModelSelect2Widget):
def filter_queryset(self, request, term, queryset=None, **dependent_fields):
if request.user.is_authenticated:
queryset = queryset.filter(user=request.user)
return super().filter_queryset(self, request, term, queryset=queryset, **dependent_fields)
If hope this example helps. Let me know if you need any further assistance.
Best -Joe
Hi @codingjoe, Thanks for your quick response.
I am using django-select2==6.0.2, and def filter_queryset
has no request
yet.
Do you have any other option?
Thanks, Nikolay
Hi @nikolaysm,
as I mentioned before I am just guessing your problem. To further assist you I really need a more detailed description of what you are trying to achieve and your form code including all widgets.
Best -Joe
My problem is that form field "participant" value is not selected. My select2 dropdown is empty, you can see it on provided screenshot.
My code
class ParticipantSelect2Widget(ModelSelect2Widget):
model = Participant
search_fields = ["firstname__icontains", "lastname__icontains"]
def label_from_instance(self, obj):
job = obj.job
title = "Job ID: %s" % job.pk if job else _("No job")
return "%s - %s" % (obj.full_name, title)
class MeetingForm(forms.ModelForm):
class Meta:
model = Meeting
fields = [
"company", "topic", "agenda", "participant",
"type_meeting", "start_time", "duration",
"password", "join_before_host","mute_upon_entry"
]
def __init__(self, *args, **kwargs):
user = kwargs.pop('user', None)
super(MeetingForm, self).__init__(*args, **kwargs)
if not user.is_staff:
queryset = Participant.objects.filter(company__pk__in=user.contact_set.values_list("business_id", flat=True))
else:
queryset = Participant.objects.all()
self.fields["participant"].widget = ParticipantSelect2Widget(
queryset=queryset,
attrs = {
'data-theme':'material', 'class':'browser-default material-ignore',
'data-minimum-input-length': 3, 'data-allow-clear':'false',
'data-placeholder':_("Choose an Participant")
}
)
Any help is appreciated Nikolay
My problem was solved by adding selected value to field.choices.
I have added below part code in def __init__
sltd_participant = self.data.get("participant") or self.initial.get("participant")
if sltd_participant:
self.fields["participant"].choices = [(sltd_participant, queryset.get(pk=sltd_participant))]
Maybe that would be interesting for ModelSelect2Widget
by default adding field value to self.fields ["field"].choices
. And if no field value, then empty self.fields ["field"].choices
.
It would be more interested if Queryset
is too large.
Then you don't need to render all the choices(select>options).
Or am I missing something?
Best, Nikolay
@nikolaysm glad you found a solution. I would advise a little change though. You see, the widget choices are set by default, you are just overwriting the widget where the choices were set. The trick is to the correct widget before the form is instantiated.
Here an example, that should work for your use case:
class ParticipantSelect2Widget(ModelSelect2Widget):
model = Participant
search_fields = ["firstname__icontains", "lastname__icontains"]
def label_from_instance(self, obj):
job = obj.job
title = "Job ID: %s" % job.pk if job else _("No job")
return "%s - %s" % (obj.full_name, title)
def filter_queryset(self, request, term, queryset=None, **dependent_fields):
if request.user.is_authenticated:
queryset = queryset.filter(company__in=request.user.user.contact_set.all())
return super().filter_queryset(self, request, queryset, **dependent_fields)
class MeetingForm(forms.ModelForm):
class Meta:
model = Meeting
fields = [
"company", "topic", "agenda", "participant",
"type_meeting", "start_time", "duration",
"password", "join_before_host","mute_upon_entry"
]
widgets = {
"participant": ParticipantSelect2Widget(attrs={
'data-theme': 'material', 'class': 'browser-default material-ignore',
'data-minimum-input-length': 3, 'data-allow-clear': 'false',
'data-placeholder': _("Choose an Participant")
})
}
I hope that helps.
Best -Joe
Hi,
I am using django-select2==6.0.2 with django 1.11.
So i add ModelSelect2Widget in
__init__
.The problem is that instance values are not selected. And dropdown field is empty. It works perfectly when I add it via widgets but not with
__init__
.The only solution that I see now is to create a custom
AutoResponseView
for ModelSelect2Widget, and add ModelSelect2Widget before__init__
.Are there other options?
Thanks