There is a form:

class CampaignLocationForm(forms.ModelForm): class Meta: model = CampaignLocation fields = ('location', 'location_type') widgets = { 'location': forms.Select( attrs={ 'class': 'form-control selectpicker', 'data-live-search': "true"} ), 'location_type': forms.Select( attrs={'class': 'form-control'} ) } 

There is a huge number of items in the location list More than 80,000. Therefore, I use Ajax-Bootstrap-Select for autocomplete. I don’t know how to set the queryset for the location field so that the initial value is empty or only the selected item is on the list (when changed)

In my view, it should look like this:

 class CampaignLocationForm(forms.ModelForm): def __init__(self, *args, **kwargs): super(CampaignLocationForm, self).__init__(*args, **kwargs) if ***если location уже задан***: self.fields['location'].queryset = ??? else: self.fields['location'].choices = (('', ''),) 

What exactly should I check and what should the queryset be?

    1 answer 1

    At each field of the form at initialization it is possible to transfer argument 'initial' in which the initial value of this field is stored. When generating a form from a model, each field of the model returns a form field with the passed value in the initial argument. An argument with the same name is at the initialization of the form itself, you can pass to it the entire instance of the model. https://docs.djangoproject.com/en/1.9/ref/forms/api/#dynamic-initial-values

    It turns out like this:

     class CampaignLocationForm(forms.ModelForm): def __init__(self, *args, **kwargs): super(CampaignLocationForm, self).__init__(*args, **kwargs) if self.fields['location'].initial: self.fields['location'].choices = (('%s' % location.pk, location.__unicode__()) for location in self.fields['location'].initial) else: self.fields['location'].choices = (('', ''),) 
    • It's clear. So far I have attached django-autocomplete-light, but for one or two fields it’s not nice to do that. There was a question: for already existing initial values ​​is passed by default? - Kamo Petrosyan
    • Yes, if you use a ModelForm with an instance of the model, then the field values ​​are usually automatically substituted. If you're interested, see how the formfield method works in models, all the magic of passing the value happens there. If the fields of the form are written manually, then usually the value can be found in self.initital. You can pull out location = self.fields ['location']. Initial or self.initial.location and then work with a local variable. - Chikiro
    • I tried. Not yet. def __init __ (self, * args, ** kwargs): super (CampaignLocationForm, self) .__ init __ (* args, ** kwargs) if self.fields ['location']. initial: location = self.fields ['location' ] .initial self.fields ['location']. queryset = self.fields ['location']. queryset.filter (location_id = location) else: self.fields ['location']. queryset = self.fields ['location '] .queryset.none () - Kamo Petrosyan
    • In self.fields ['location']. Initial anything passed? And in self.initial? - Chikiro