Django在表单集中显示值文本

Posted

技术标签:

【中文标题】Django在表单集中显示值文本【英文标题】:Django display value text in formset 【发布时间】:2020-08-01 23:57:12 【问题描述】:

我想在模板上显示外键的文本值,用户无法更改它。 模板:

% for form in formset %
    <div class="">
        % for field in form %
             field 
        % endfor %
    </div>
% endfor %

html 渲染:

<select name="form-0-semestre_solicitacao" id="id_form-0-semestre_solicitacao">
  <option value="">---------</option>
  <option value="5">2020/1</option>
  <option value="4">2019/2</option>
  <option value="3" selected="">2019/1</option>
  <option value="2">2018/2</option
  <option value="1">2018/1</option>
</select>

我试过 field.initial and field.value ,但它显示3,我希望它显示文本:2019/1

更新: display 中的字段是指 semestre_solicitacao 中的外键 模型.py

class Solicitacao(models.Model):
    """Solicitações, depende de User e curso"""
    #TODO trocar homologada de boolean para choice homologada e não homologada, e ajustar forms
    solicitante = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    disciplina = models.ForeignKey(Disciplina, on_delete=models.CASCADE)
    justificativa = models.TextField(("Justificativa para o pedido"),
                                     help_text="O candidato pode explicar os motivos para solicitar a prova, por exemplo: experiência profissional, cursos não regulares, aproveitamentos indeferidos, entre outros.", blank=True, null=True)
    documentos = models.FileField(("Documentos comprobatorios de conhecimentos"),
                                  upload_to=None, max_length=100, blank=True, null=True,
                                  validators=[FileExtensionValidator(['.pdf'])])
    data_solicitacao = models.DateTimeField(
        ("Data da solicitação"), auto_now_add=True)
    cursou_anteriormente = models.BooleanField(
        ("Cursou anteriormente a disciplina solicitada"), blank=True, null=True)
    homologada = models.BooleanField(blank=True, null=True)
    semestre_solicitacao = models.ForeignKey(Calendario, on_delete=models.CASCADE, null=True)

Views.py

from extra_views import ModelFormSetView
class ItemFormSetView(ModelFormSetView):
    model = Solicitacao
    fields = ['semestre_solicitacao', 'solicitante', 'disciplina', 'cursou_anteriormente']
    template_name = 'manage_solicitacoes.html'
    success_url = reverse_lazy('cc:solicitacoes')
    factory_kwargs = 'extra': 0

    def get_queryset(self):
        slug = self.kwargs['slug']
        return super(ItemFormSetView, self).get_queryset().filter(semestre_solicitacao__slug=slug)

我正在使用 django-extra-views。

更新 2: I'm getting the top part of the image, and i would like something similar to the one in the bottom

其他型号:

  class Calendario(models.Model):
    """Calendario referente as datas do semestre"""
    ano = models.CharField(
        ("Ano"), max_length=4,
        help_text='Ano dos pedidos, ex: 2020')
    semestre = models.CharField(
        ("Semestre"), max_length=1,
        help_text='Semestre dos pedidos')
    is_active = models.BooleanField('Calendário em vigor', default=True)
    inicio_solicitacoes = models.DateField(
        "Inicío das Solicitações", auto_now=False, auto_now_add=False)
    fim_solicitacoes = models.DateField(
        "Fim das Solicitações", auto_now=False, auto_now_add=False)
    inicio_recursos = models.DateField(
        "Inicío dos Recursos", auto_now=False, auto_now_add=False)
    fim_recursos = models.DateField(
        "Fim dos Recursos", auto_now=False, auto_now_add=False)
    slug = models.SlugField(unique=True)

    class Meta():
        ordering = ['-ano', '-semestre']
        constraints = [
            models.UniqueConstraint(
                fields=['ano', 'semestre'], name='unique_ano_semestre')
        ]

    def __str__(self):
        return f'self.ano/self.semestre'

    def get_absolute_url(self):
        return reverse("calendario:calendario-detail", kwargs="slug": self.slug)

    def get_delete_url(self):
        return reverse("calendario:calendario-delete", kwargs="slug": self.slug)

    def save(self, *args, **kwargs):
        """Garante que exista apenas um is_active=True e define a slug"""    
        slug_str = f'self.ano-self.semestre'
        unique_slugify(self, slug_str)
        if self.is_active:
            with transaction.atomic():
                Calendario.objects.filter(
                    is_active=True).update(is_active=False)
                return super(Calendario, self).save(*args, **kwargs)
        else:
            return super(Calendario, self).save(*args, **kwargs)

    def get_fields(self):
        """ Permite usar for no template para exibir todos os atributos do objeto"""
        return [(field.verbose_name, field.value_to_string(self)) for field in Calendario._meta.fields]


class Curso(models.Model):
    """Cursos existente e ativos com matriz"""
    nome = models.CharField(max_length=30)
    abreviacao = models.CharField(
        'Abreviação', max_length=3, help_text='Máximo 3 letras')
    matriz = models.CharField(
        max_length=4, help_text='Ano de aprovação de matriz do curso')
    is_active = models.BooleanField('Ativo', default=True)
    slug = models.SlugField(max_length=20)

    class Meta():
        ordering = ['-is_active', 'nome']

    def save(self, *args, **kwargs):
        slug_str = self.abreviacao + self.matriz
        unique_slugify(self, slug_str)
        self.abreviacao = self.abreviacao.upper()
        super(Curso, self).save(*args, **kwargs)

    def __str__(self):
        return f'self.abreviacao/self.matriz'

    def get_absolute_url(self):
        return reverse("curso:curso-detail", kwargs="slug": self.slug)

class Disciplina(models.Model):
    """Modelo disciplina"""
    codigo = models.CharField(("Código"), max_length=12, primary_key=True, unique=True)
    nome = models.CharField(("Nome da disciplina"), max_length=50)
    curso = models.ManyToManyField('Curso')

    def __str__(self):
        return f'self.codigo - self.nome'

    def get_absolute_url(self):
        """Url para o template com detalhes de uma disciplinas especifica"""
        return reverse("curso:disciplina-detail", kwargs="pk": self.codigo)

【问题讨论】:

我假设您的选择值是静态的(即不是来自 DB),请使用 choices 在 formField 或 modelField 中显示选择 它们是外键,我会用模型更新问题 如果涉及外键,那么我猜 1,2,3,4 是 ID 值。您可以在输入 FK 数据时添加一些 yearMonthvalue 字段并将其值设置为 20YY/MM,并在 str 方法中返回该 yearMonthvalue。我想这应该可以解决您的问题。 是的,这些是 ID,不明白我是怎么做到的,我尝试过 field.initial.__str__ 但我不接受。我放了一张图片,以便更好地了解我想要做什么。 【参考方案1】:
 form.instance.solicitante  e  form.instance.solicitante.curso 

做了我想做的事

【讨论】:

以上是关于Django在表单集中显示值文本的主要内容,如果未能解决你的问题,请参考以下文章

Django:如何显示内联表单集中每个模型对象的表单错误

表格的每一行中的 Django 表单

JQuery Buttons 加上变量值填充文本表单

在内联表单集中使用 Django FileField

在 Django 表单中水平对齐单选按钮

Django - 禁用表单集中现有表单的编辑,但允许在新表单中编辑