Django. Как полностью скрыть поля в форме?

301
30 ноября 2020, 01:20

Подскажите, пожалуйста, как полностью скрыть поля в форме, сейчас скрывает только поле, но название поля остаётся?

Модель объявления:

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='Описание')
    series = models.ForeignKey(Series, on_delete=models.CASCADE, verbose_name='Серия')
    rooms = models.IntegerField(default=0, blank=True, verbose_name='Количество комнат')
    sqmt = models.IntegerField(default=0, blank=True, verbose_name='Площадь')
    price = models.IntegerField(default=0, blank=True, verbose_name='Цена')
    photo_main = models.ImageField(upload_to='photos/%Y/%m/%d/', blank=True, verbose_name='Основное фото')
    photo_1 = models.ImageField(upload_to='photos/%Y/%m/%d/', blank=True, verbose_name='Фото 1')
    photo_2 = models.ImageField(upload_to='photos/%Y/%m/%d/', blank=True, verbose_name='Фото 2')
    photo_3 = models.ImageField(upload_to='photos/%Y/%m/%d/', blank=True, verbose_name='Фото 3')
    photo_4 = models.ImageField(upload_to='photos/%Y/%m/%d/', blank=True, verbose_name='Фото 4')
    photo_5 = models.ImageField(upload_to='photos/%Y/%m/%d/', blank=True, verbose_name='Фото 5')
    photo_6 = models.ImageField(upload_to='photos/%Y/%m/%d/', blank=True, verbose_name='Фото 6')
    is_published = models.BooleanField(default=True, verbose_name='Публично')
    list_date = models.DateTimeField(default=datetime.now, blank=True, verbose_name='Дата публикации')
    def __str__(self):
        return self.title

forms.py

class ListingForm(forms.ModelForm):
    class Meta:
        model = Listing
        exclude = ('realtor',)
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['city'].queryset = City.objects.none()
        if 'region' in self.data:
            try:
                region_id = int(self.data.get('region'))
                self.fields['city'].queryset = City.objects.filter(region_id=region_id).order_by('name')
            except (ValueError, TypeError):
                pass  # неверный ввод от клиента; игнорирование и возврат к пустому набору запросов City
        elif self.instance.pk:
            self.fields['city'].queryset = self.instance.region.city_set.order_by('name')
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['district'].queryset = District.objects.none()
        if 'city' in self.data:
            try:
                city_id = int(self.data.get('city'))
                self.fields['district'].queryset = District.objects.filter(city_id=city_id).order_by('name')
            except (ValueError, TypeError):
                pass
        elif self.instance.pk:
            self.fields['district'].queryset = self.instance.city.district_set.order_by('name')

При выборе категории, ненужные поля скрываются, но надписи остаются, а прописать div, который необходимо скрыть полностью я не могу, а то, что скрылось, я посмотрел код страницы в браузере:

<div class="card-body">
<form method="POST" id="ListingForm" data-cities-url="{% url 'ajax_load_cities' %}" data-districts-url="{% url 'ajax_load_districts' %}" novalidate enctype="multipart/form-data">
   {% csrf_token %}
   {% bootstrap_form form %}
<input type="submit" value="Добавить" class="btn btn-secondary btn-block">
</form>
</div>
$('#id_category').change(function () {
          var optionSelected = $("option:selected", this);
          var valueSelected = $(this).val();
          if (valueSelected === '1') {
            $('#id_rooms').hide();
            $('#id_series').hide();            
          } else if (valueSelected === '2') {
            $('#id_rooms').hide();
            $('#id_series').hide();
          } else {
            $('#id_rooms').show();
            $('#id_series').show();
          }
        });

Answer 1
{% bootstrap_form(exclude=series,rooms) form %}
Answer 2
  1. Измените в модели поля series и rooms. В них должны быть null=True, blank=True.
  2. В форме в exclude добавьте эти поля.
Answer 3

Изменение видимости полей формы в зависимости от выбранных значений можно реализовать только через js - в частности через событие onchange менять видимость либо тип поля

Если вы хотите скрывать некоторые поля изначально, то вы можете использовать ручной вывод в шаблоне для каждого поля с условием:

{% for field in form %} 
    {{ field.errors }} 
    <div class="fieldWrapper" 
    {% if  field.id_for_label == 'id_series' %} 
        style="display:None" 
    {% end if %}> 
        {{ field.label_tag }} {{ field }}
     </div> 
{% endfor %}

Тогда некоторые поля могут оставаться скрытыми изначально. Как альтернативу display:None можете использовать {{form.field.as_hidden }}

Так же в джанго есть возможность итерировать именно видимые поля, которые игнорируют виджеты с input=hidden (вы можете переопределить виджеты в вашей форме) :

widgets = { 
       'series': forms.InputHidden()
} 

И сама итерация:

{% for hidden in form.hidden_fields %}       
     {{ hidden }} 
{% endfor %}
{% for field in form.visible_fields %} 
    <div class="fieldWrapper">      
    {{ field.errors }} {{ field.label_tag }} {{ field }} 
    </div> 
{% endfor %}
Answer 4
$('#id_category').change(function () {
      var optionSelected = $("option:selected", this);
      var valueSelected = $(this).val();
      if (valueSelected === '1') {
        $('#id_rooms').parent().hide();
        $('#id_series').parent().hide();            
      } else if (valueSelected === '2') {
        $('#id_rooms').parent().hide();
        $('#id_series').parent().hide();
      } else {
        $('#id_rooms').parent().show();
        $('#id_series').parent().show();
      }
    });
READ ALSO
Парсинг на клиенте

Парсинг на клиенте

Необходимо на клиенте получить данные с другого сайтаНужная информация на странице другого сайта хранится в

100
Как написать счетчик ОСТАЛОСЬ попыток 3

Как написать счетчик ОСТАЛОСЬ попыток 3

Вот мой скриптНе могу понять почему после ввода продолжает проверять цикл? Задача следущая: При посещении страницы, необходимо попросить...

105
Проблема конкатенации media правил

Проблема конкатенации media правил

Дело в том что при построении кода таким образом, когда @media правила разбросаны по всем файлам, появляется потребность в их конкатенации в одно...

111
галерея на grid css

галерея на grid css

есть галерея выполненная на css grid

138