【问题标题】:Django: Using Radio select box on model formsetsDjango:在模型表单集上使用 Radio 选择框
【发布时间】:2011-06-11 10:30:29
【问题描述】:

嘿, 我正在使用模型表单集让我的用户编辑他们的相册。我想在每张照片上放置一个收音机选择框,上面写着“设置为封面图片”,这样我就可以处理所有照片并找到应该成为专辑封面的照片。问题是我如何才能在表单集上使用无线电选择字段并仍然与其他照片保持相互关系?这是我当前的代码:

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

【问题讨论】:

    标签: django select field radio formset


    【解决方案1】:

    资格:

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

    【讨论】:

      【解决方案2】:

      根据@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())
      

      【讨论】:

        【解决方案3】:

        我喜欢简洁的模板文件,因此为此我制作了一个自定义小部件。

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

        希望对大家有所帮助

        【讨论】:

          【解决方案4】:

          我认为这里的关键是单选按钮实际上并不是表单集的一部分:它是父表单的一部分。实际的相册模型需要知道哪些照片对象是封面图像。因此,您要做的是将单选按钮中的每个选项显示在 Photo formset 中相应行的旁边 - 这是棘手的一点,因为 Django 无法以这种方式呈现表单字段。您需要手动为每个选项生成 HTML。

          所以,给定这些表格,并假设 Album 模型有一个 cover_image,它是一个到 Photo 的 OneToOneField:

          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 %}
          

          【讨论】:

            猜你喜欢
            • 2015-07-06
            • 2018-07-14
            • 2012-11-23
            • 2012-05-02
            • 2013-07-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多