1

ねえ、私はモデルフォームセットを使用して、ユーザーがフォトアルバムを編集できるようにしています。すべての写真に「カバー画像として設定」というラジオ選択ボックスを配置して、すべての写真を処理し、アルバムのカバーにする必要がある写真を見つけられるようにします。問題は、ラジオを使用してフィールドをフォームセットに選択し、残りの写真でそれをミュートに保つにはどうすればよいですか?これは私の現在のコードです:

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

4 に答える 4

3

ここで重要なのは、ラジオ ボタンが実際にはフォームセットの一部ではなく、親フォームの一部であるということです。どの Photo オブジェクトがカバー画像であるかを知る必要があるのは、実際の Album モデルです。つまり、Photo フォームセットの対応する行の横にラジオ ボタンの各オプションを表示する必要があります。Django ではフォーム フィールドをそのようにレンダリングできないため、これは注意が必要です。各オプションの HTML を手動で作成する必要があります。

cover_imageしたがって、これらのフォームが与えられ、Album モデルに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 %}
于 2011-01-20T10:49:03.980 に答える
1

私はきちんとしたテンプレート ファイルが好きなので、この目的のためにカスタム ウィジェットを作成しました。

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))

それが誰かを助けることができることを願っています

于 2013-03-24T23:01:44.963 に答える
0

@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())
于 2015-08-17T08:31:11.377 に答える