Django. Как скрыть ненужные поля в форме в зависимости от выбранной категории?

Все привет. Мне нужно сделать так, чтобы при добавлении нового объявления, выбирая категорию, скрывались ненужные поля в форме. Понимаю, что это делается чере JS, но я пока плохо разбираюсь, поэтому прошу подсказать, если кто хорошо разбирается.
Например, я хочу, чтобы при выборе "Дома и участки" исчезал "Этаж":
5cc6b7c5a1850755852236.png
Вот моя главная модель:
class Listing(models.Model):
	realtor = models.ForeignKey(Realtor, on_delete=models.CASCADE, verbose_name='Риелтор')
	category = models.ForeignKey(Category, on_delete=models.CASCADE, verbose_name='Категория')
	region = models.ForeignKey(Region, on_delete=models.CASCADE, verbose_name='Область')
	city = models.ForeignKey(City, on_delete=models.CASCADE, verbose_name='Город')
	district = models.ForeignKey(District, on_delete=models.CASCADE, verbose_name='Район')
	title = models.CharField(max_length=200, verbose_name='Заголовок')
	landmark = models.CharField(blank=True, max_length=200, verbose_name='Ориентир')
	description = models.TextField(blank=True, verbose_name='Описание')
	stage = models.IntegerField(default=0, blank=True, verbose_name='Этаж')
	rooms = models.IntegerField(default=0, blank=True, verbose_name='Количество комнат')

forms.py:
class ListingForm(forms.ModelForm):
    class Meta:
        model = Listing
        exclude = ('realtor',)

Форма в шаблоне:
<form method="POST"  novalidate enctype="multipart/form-data">
   {% csrf_token %}
   {% bootstrap_form form %}
   <input type="submit" value="Добавить" class="btn btn-secondary btn-block">
</form>

Посмотрел в браузере структуру формы в шаблоне:
<div class="form-group">
<label for="id_category">Категория</label>
<select name="category" class="form-control" title="" required id="id_category">
  <option value="" selected>---------</option>
  <option value="1">Квартиры</option>
  <option value="2">Коммерческое</option>
  <option value="3">Дома и участки</option>
</select></div>

Структура поля, которое я хочу скрыть:
<div class="form-group">
<label for="id_stage">Этаж</label>
<input type="number" name="stage" value="0" 
class="form-control" placeholder="Этаж" title="" id="id_stage">
</div>

Попробовал сделать так, но пока не работает:
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
  <script>
    $('#id_category').change(function () {
      var optionSelected = $("option:selected", this);
      var valueSelected = $(this).val();
      
      if (valueSelected === 3){
          $('#id_rooms').hide();
      } else {
          $('#id_rooms').show();
      }
    });
  </script>

Если знаете, подскажите, пожалуйста, или пример какой, как это делается. Заранее, спасибо.
  • Вопрос задан
  • 192 просмотра
Пригласить эксперта
Ответы на вопрос 3
@Igorell0
Я хоть и начинающий веб, но у меня такое ощущение, что копать надо в сторону клиентской части, а именно -- JS. Посмотрите на спецресурсах какое-нибудь событие, вызываемое по заполнению формы (см. на том же javascript.ru) и в нём делать вызов к DOM'у чтобы скрыть элемент. Если что, можно куда-нибудь в JS топик кинуть вопрос, мол как по заполнению выпадающего меню скрыть какой-то другой элемент. Как-то так.
Ответ написан
@IceHummer
Как-то очень давно делал подобное, но для формы адреса. Брал идею с PayPal
https://www.ushanka.com/ вот на этом сайте, добавите товар в корзину и перейдете в саму корзину, далее "Pay with card". Но на этом сайте было критично только для USA, поэтому на все страны у меня настроена default форма, а USA специфичная.
Делается подобное через GET запрос к view которая на вход принимает параметр category (желательно строковый параметр slug), далее во view происходит import нужной Form из forms.py вашего приложения, в случае отсутствия специфичного класса под категорию, через исключение импортируете DefaultCategoryForm, таким же образом подтягиваете шаблон, можно использовать select_template(). Далее этот кусочек формы рендерите и вставляете в ваш HTML.
Но также нужно учесть что при валидации вам нужно подставлять нужную форму. Собрать ее лучше на лету через type().

В другом проекте более простом, я использовал betterforms. Там нужно создавать группы форм, а на атрибут class вешать например slug тех категорий полей которые нужно отображать для конкретной категории. Но этот вариант подойдет для не обязательных полей. То есть везде его использовать не получится
Ответ написан
@776166
Варианов два: на фронте и на бэке.
На фронте надо jsкриптить. На бэке можно сделать вьюху, в которую при изменении будет аякситься форма или целиком перезагружать страницу, перерасчитывая форму и возвращать её обратно.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы