0

I have a Django model like:

class hotel(models.Model):
   name = models.CharField(max_length=60)
   city = models.ForeignKey('city', on_delete=models.DO_NOTHING)
   state = models.ForeignKey('state', on_delete=models.DO_NOTHING)
   country = models.ForeignKey('country', on_delete=models.DO_NOTHING)
   def __str__(self):
       return self.name
   class Meta:
       verbose_name_plural = "hotels"

class city(models.Model):
   name = models.CharField(max_length=60)
   state = models.ForeignKey('state', on_delete=models.DO_NOTHING)
   def __str__(self):
       return self.name
   class Meta:
       verbose_name_plural = "cities"

class state(models.Model):
   name = models.CharField(max_length=60)
   country = models.ForeignKey('country', on_delete=models.DO_NOTHING)
   def __str__(self):
       return self.name
   class Meta:
       verbose_name_plural = "states"

class country(models.Model):
   name = models.CharField(max_length=60)
   code = models.CharField(max_length=160)
   def __str__(self):
       return self.name
   class Meta:
       verbose_name_plural = "countries"

And the ModelForm like:


class Hotel(ModelForm):
    class Meta:
        model = hotel
        fields = '__all__'

[EDIT] When creating form object from Hotel ModelForm, Django automatically fills values of foreignkey fields. I want to stop that.

For example:

form = Hotel() (Django auto-populates city, state and country values)

I want my Django template to return all country values in dropdown, but not for state and city dropdowns (so I want state and city dropdowns to remain empty in Django template). How can I do that?

PS - The purpose to do this is to load country values first, and as per the user selection of a country, I will load state and then cities accordingly.

J J
  • 43
  • 7
  • Instead of using `fields='__all__'`, specify the fields you want the values to be loaded from DB. A simple example would be like the one specified in https://simpleisbetterthancomplex.com/tutorial/2018/01/29/how-to-implement-dependent-or-chained-dropdown-list-with-django.html – JRajan Dec 30 '19 at 09:51
  • True. I could use 'exclude' and manually write html elements for state and city, but I want to make use of pre-defined form elements of Django in my views. – J J Dec 30 '19 at 10:02
  • Got it. The example that I had linked had the similar example code for empty dropdowns as the accepted answer. :) – JRajan Dec 31 '19 at 08:02

1 Answers1

1

You can override the choices either in the form __init__ method or you can use a little trick with setting choices just after the field has been defined

class Hotel(ModelForm):

    class Meta:
        model = hotel
        fields = '__all__'

    # Like this
    state = forms.ModelChoiceField(state.objects.all())
    state.choices = []
    city = forms.ModelChoiceField(city.objects.all())
    city.choices = []

    # Or like this...
    def __init__(self, data=None, *args, **kwargs):
        super().__init__(data=data, *args, **kwargs)
        if not data:
            self.fields['state'].queryset = state.objects.none()
            self.fields['city'].queryset = state.objects.none()
Iain Shelvington
  • 31,030
  • 3
  • 31
  • 50