【问题标题】:Multiple sub-fields attached to a field, and how to give the user the possibility of adding many of these fields附加到一个字段的多个子字段,以及如何为用户提供添加许多这些字段的可能性
【发布时间】:2019-12-18 09:58:25
【问题描述】:

我正在构建一个表单,用户(作曲家)可以在其中添加作品。在此表单中,除了标题、年份等之外,他们还添加了工具。

每种乐器都可以有几个属性,例如“加倍”和玩家人数。

例如:

  • 标题:新作文
    • 仪器:
      • 小提琴
        • 加倍:没有
        • 玩家:1(这是“DoublingAmount”,见模型)
      • 中提琴
        • 加倍:是的
        • 玩家:2(这是“DoublingAmount”,见模型)
      • 大提琴
        • 加倍:没有
        • 玩家:4(这是“DoublingAmount”,见模型)

我创建了三种不同的模型:一种用于仪器,一种用于合成,然后一种通过“通过”具有多对多关系。

models.py:

class Composition(models.Model):

    title       = models.CharField(max_length=120) # max_length = required
    INSTRUMENT_CHOICES = [('pno', 'piano'), ('vio1', 'violin_1(orchestral section)'), ('vio2', 'violin_2(orchestral section)'),]
    instrumentation = models.ManyToManyField('Instrumentation',
        through='DoublingAmount',
        related_name='compositions',
        max_length=10,
        choices=INSTRUMENT_CHOICES,)

class Instrumentation(models.Model):

    instrumentation = models.CharField(max_length=10)

class DoublingAmount(models.Model):

    DOUBLING_CHOICES =[(1, '1'),(2, '2'), (3, '3')]

    doubling = models.BooleanField(default=False)
    composition = models.ForeignKey(Composition, related_name='doubling_amount', on_delete=models.SET_NULL, null=True)
    instrumentation = models.ForeignKey(Instrumentation, related_name='doubling_amount', on_delete=models.SET_NULL, null=True)
    amount = models.IntegerField(choices=DOUBLING_CHOICES, default=1)

forms.py:

from django import forms
from .models import Composition, Instrumentation

class CompositionForm(forms.ModelForm):
    title       = forms.CharField(label='Title',
                    widget=forms.TextInput()
    description = forms.CharField()


    class Meta:
        model = Composition
        fields = [
            'title',
            'instrumentation',
        ]

views.py:

def composition_create_view(request):

    form = CompositionForm(request.POST or None)
    if form.is_valid():
        form.save()
        form = CompositionForm()
    context = {
        'form': form
    }
    return render(request, "template.html", context)

模板.html:

    {{ form }}

我可以在我的表单中看到下拉列表,其中提供了工具名称的选择,仅此而已。我希望可以选择仪器名称,加倍是/否和数量。然后我还想添加更多乐器,每个乐器都有自己的名称、倍数和数量。我知道这必须通过 JavaScript 完成,但我不知道如何构建“幕后”并让 Django 抓取用户添加的新项目。

更新

我在 forms.py 中添加了一个新表单:

class InstrumentationForm(forms.ModelForm):

    class Meta:
        model = DoublingAmount
        fields = [
            'doubling',
            'amount',
            'instrumentation'
        ]

并链接到views.py:

form_d = InstrumentationForm(request.POST or None)
    [...]
    context = {
        'form': form,
        'form_d': form_d
    }

最后是模板:

{{ form_d }}

现在我的模板中显示了检测、加倍和金额字段。我这样做对吗?如果是,我如何让 Django 处理想要添加或删除仪器的用户?谢谢。

更新 2

我刚刚意识到的问题是,如果我使用 DoublingAmount 模型来存储有关合成乐器的信息,则需要已经创建对象合成,当然情况并非如此。一种解决方案可能是构建另一个表单,在用户保存组合标题后仅显示“DoublingAmount”(例如仪器)信息。不过,我不知道如何在 DoublingAmount 模型中拥有多个工具,而没有多个 DoublingAmount 对象用于同一组合。

有没有更简单的方法来完成这一切?例如,组合模型的“子类”?

【问题讨论】:

    标签: django python-3.x django-models django-forms


    【解决方案1】:

    创建一个组合,然后将一个又一个乐器(如 cmets)添加到博客文章中。这可能是最简单的方法。可悲的是,我不知道如何从 Django 中的表单创建对象数组。这是拥有多个对象的正确方法,这就是为什么它是ManyToMany。我还建议 OneToMay 和两个课程: 具有以下字段的作曲和乐器:名称,加倍,玩家人数。但我也没有真正得到这个音乐家的东西所以也许我错了:-)

    另一种方法是使用 Ajax 或类似的东西并在 json 中创建一个数组并将其转换为您的工具。如果您想动态添加更多工具,则无论如何都需要 js(您需要创建输入字段等)。

    【讨论】:

    • 谢谢,我整天都在与这个作斗争,但我仍然处于僵局。我现在正在尝试使用 Django 表单集,但到目前为止无济于事。我可能最终完全放弃,或者像以前一样只使用两个课程。会及时通知您!
    • 这对你来说可能很有趣:medium.com/all-about-django/…
    • 谢谢 - 这是我下午尝试的,当时我说我正在尝试使用表单集。我现在找到了另一个可能对我有帮助的指南,祈祷。我会在这里发布任何更新(希望我很快就会有)。
    • 谢谢,我实际上遵循了一个更新的教程,今天早上我终于设法让它工作了。我稍后会发布我的工作代码。最后,我恢复了我最初的想法,即拥有三种不同的模型,并带有自定义的“通过”。我越来越喜欢 Django。
    猜你喜欢
    • 1970-01-01
    • 2020-11-07
    • 2013-04-07
    • 2015-06-11
    • 1970-01-01
    • 2011-04-20
    • 2011-09-21
    • 1970-01-01
    • 2013-07-12
    相关资源
    最近更新 更多