首页 > 解决方案 > 如何创建和启动表单选择字段,而不是在模型中?

问题描述

我已经在这个论坛和西班牙语中回顾了许多与这个主题相关的问题,我已经按照步骤进行操作,但它对我不起作用,起初看起来很简单。我有Django 2.2.6的表单,该表单需要 Select 字段的选定值,该字段不在模型中,并获取从视图创建的值列表(两个元组)。

输入表单后,抛出此错误:"__init __ () received an unexpected keyword argument 'carpetas'",在FotoArtForm类中,在super ()行中。这是我的代码:

模型.py

class FotoArt(models.Model):
    nombre = models.CharField(max_length=50)
    foto = models.ImageField(upload_to='fotos/articulos/', null=True, blank=True)

    class Meta:
        ordering = ['nombre']
        verbose_name = _('Foto Artículo')
        verbose_name_plural = _('Fotos Artículos')

    def __str__(self):
        return self.nombre

    def get_absolute_url(self):
        return reverse('detalle-fotoArt', args=[str(self.id)])

视图.py

class FotoArtActualizar(LoginRequiredMixin, UpdateView):
    model = FotoArt
    form_class = FotoArtForm 
    Ruta = os.path.join(MEDIA_ROOT, 'fotos', 'articulos')

    def get_form_kwargs(self):
        kwargs = super(FotoArtActualizar, self).get_form_kwargs()
        kwargs['carpetas'] = self.get_folders_list(self.Ruta)
        return kwargs

    def get_folders_list(self, ruta):
        foldersList = []
        for _, listaSubDir, _ in os.walk(ruta):
            for dName in listaSubDir:
                foldersList.append((dName, dName))
        return foldersList

表格.py

class FotoArtForm(forms.ModelForm):
    guardar_en_carpeta = forms.ChoiceField(choices=(), required=True)

    def __init__(self, *args, **kwargs):
        super(FotoArtForm, self).__init__(*args, **kwargs)
        self.foldersList = kwargs.pop('carpetas', None)

    self.fields['guardar_en_carpeta'].choices = self.foldersList

    class Meta:
        model = FotoArt
        fields = ['nombre', 'guardar_en_carpeta', 'foto']

fotoArt_form.html

{% extends 'catalogo/base.html' %}

{% block content %}
    <h2>Crear/Actualizar Fotos Artículos</h2>
    <hr/>
    <form action="" method="post" enctype="multipart/form-data">
        {% csrf_token %}
        {{ form.non_field_errors }}

        <div class="input-group mb-3">
          <div class="input-group-prepend">
            <label class="input-group-text font-weight-bold" for="inputCarpeta">Guardar en carpeta</label>
          </div>
          {{ form.guardar_en_carpeta.errors }}
          {{ form.guardar_en_carpeta }}
        </div>

        {{ form.foto.errors }}
        <strong>{{ form.foto.label_tag }}</strong>
        {{ form.foto }}

        <div class="form-group row my-2">
           <label for="nombreFoto" class="col-sm-2 col-form-label"><strong>Nombre</strong></label>
            {{ form.nombre.errors }}
           <div class="col-sm-10">
               {{ form.nombre }}
           </div>
            <input type="submit" value="Enviar" />
        </div>
    </form>
{% endblock %}

知道为什么我会收到此错误吗?

也许,您应该采用另一种方法将文件夹列表(选择)传递给表单的 save_in_folder 字段;而不是覆盖 get_form_kwargs () 方法,我可以覆盖 get_context_data () 方法并将其传递给上下文 ['folders_list'],但是我无法控制 save_in_folder 选择器的值以在另一个字段中使用它。

标签: django

解决方案


您尚未在中定义该carpetas字段,FotoArtForm.Meta.fields但您正在通过表单传递该字段的数据,因此来自FotoArtForm初始化程序的错误carpetas不是有效的命名参数。

您需要将语句反转为pop-outcapetas命名参数,以便在ModelForm.__init__没有它的情况下调用:

class FotoArtForm(forms.ModelForm):
    ...
    ...
    def __init__(self, *args, **kwargs):
        self.foldersList = kwargs.pop('carpetas', None)
        super(FotoArtForm, self).__init__(*args, **kwargs)

推荐阅读