Django: с помощью переключателя Radio на модельных наборах - PullRequest
1 голос
/ 19 января 2011

Эй, Я использую набор форм модели, чтобы мои пользователи могли редактировать свои фотоальбомы. Я хочу поставить флажок выбора радио на каждой фотографии с надписью «Сделать обложкой», чтобы я мог обработать все фотографии и найти того, кто должен быть обложкой альбома. Проблема в том, как я могу выбрать поле с радио на наборе форм и при этом сохранить его взаимным с остальными фотографиями? Это мой текущий код:

class ProjectGalleryForm(forms.ModelForm):
    remove_photo = forms.BooleanField()
    # set_as_cover_image = .... ?? <-- what to put?
    class Meta:
        model = Photo
        exclude = (
            'effect',
            'caption',
            'title_slug',
            'crop_from',
            'is_public',
            'slug',
            'tags'
        )

Ответы [ 4 ]

3 голосов
/ 20 января 2011

Я думаю, что ключ здесь в том, что переключатель на самом деле не является частью набора форм: это часть родительской формы. Это фактическая модель альбома, которая должна знать, какой из объектов Photo является изображением обложки. Итак, что вы хотите сделать, это отобразить каждый параметр из переключателя рядом с соответствующей строкой в ​​наборе форм «Фото» - и это хитрый момент, потому что Django не может отображать поля формы таким образом. Вам нужно будет создать HTML-код для каждого параметра вручную.

Итак, учитывая эти формы и предполагая, что модель Album имеет cover_image, который является OneToOneField to Photo:

class AlbumForm(forms.modelForm):
    class Meta:
        model = Album

photo_formset = forms.inlineformset_factory(Album, Photo, form=ProjectGalleryForm)

в шаблоне вы бы сделали что-то вроде:

{% for photo_form in photo_formset %}
    <tr><td>
    {% if photo_form.instance.pk %}
        <input type="radio" id="id_cover_image_{{ forloop.counter }}" name="cover_image" value="{{ photo_form.instance.pk }}">
        <label for="id_cover_image_{{ forloop.counter }}">Use as cover image</label>
    {% endif %>
    </td><td>{{ photo_form.as_p }}</td>
    </tr>
{% endfor %}
1 голос
/ 25 марта 2013

Мне нравится иметь аккуратный файл шаблона, и поэтому я создал для этого специальный виджет.

class SingleRadioInput(Input):

    input_type = 'radio'
    def render(self, value, checked, attrs=None):
        output = []
        if value:
            is_cover = ''
            if checked : is_cover = 'checked'
            output.append(
                ('<input type="radio" name="inline" value="%s" %s/>') 
                % (value, is_cover)
            )

        return mark_safe(u''.join(output))

Надеюсь, что это может кому-то помочь

0 голосов
/ 08 мая 2019

Квалификация:

<option value='10th' {% if '10th' in i.qf %} selected='select' {% endif %}>10th</option>
<option value='12th' {% if '12th' in i.qf %} selected='select' {% endif %}>12th</option>
<option value='graduted' {% if 'Graduated' in i.qf %} selected='select' {% endif %}>Graduated</option>
 </select>
<br><br>
0 голосов
/ 17 августа 2015

Основываясь на ответе @Mikou, вот мое более полное решение.

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

class SingleRadioInput(forms.widgets.Input):
input_type = 'radio'
def render(self, name, value, attrs=None):
    final_attrs = self.build_attrs(attrs, type=self.input_type)
    output = []
    if name:
        is_checked = ''
        if value:
            is_checked = 'checked'
        output.append(
            ('<input id="%s" type="radio" name="%s" value="%s" %s/>')
            % (final_attrs['id'], final_attrs['name'], final_attrs['instance_id'], is_checked )
        )
    return mark_safe(u''.join(output))

Моя форма объекта выглядиттаким образом, он будет автоматически выбирать объект, если поле default == True

class ObjectForm(forms.ModelForm):

def __init__(self, *args, **kwargs):
    super(ObjectForm, self).__init__(*args, **kwargs)
    self.fields['default'].widget.attrs.update({'instance_id': self.instance.id, 'name': 'default'})
    if self.instance.default:
        self.fields['default'].widget.attrs.update({'value': True})


class Meta:
    model = MyModel
    fields = ['default']
    widgets = {
        'default': SingleRadioInput(),
    }

Вот мой набор форм

ProductReferenceFormset = inlineformset_factory(ParentModel, MyModel,
                                            form=ObjectForm,
                                            extra=0, can_delete=False, can_order=False)

Я отказался от обработки части сохранения в форме, этона самом деле не стоит сложности, я думаю ... Итак, часть сохранения находится в form_valid() в View

def form_valid(self, form, price_form):
    form.save()
    # save the default radio
    MyModel.objects.filter(parent=self.object).update(default=False)
    MyModel.objects.filter(id=self.request.POST.get('default')).update(default=True)

    return HttpResponseRedirect(self.get_success_url())
...