0

我不确定这是否可能。我正在尝试使用 Django (2.0)FormFormset 视图。这是我的模型:

from uuid import uuid4

class Aliment(models.Model):
    id = models.CharField(max_length=36, primary_key=True, unique=True, default=uuid4, editable=False)
    libelle = models.CharField(max_length=50)
    def __str__(self):
        return self.libelle

class Menu(models.Model):
    id = models.CharField(max_length=36, primary_key=True, unique=True, default=uuid4, editable=False)
    libelle = models.CharField(max_length=50)
    aliments = models.ManyToManyField(Aliment, through='Ingredient')
    def __str__(self):
        return self.libelle

class Ingredient(models.Model):
    id = models.CharField(max_length=36, primary_key=True, unique=True, default=uuid4, editable=False)
    aliment = models.ForeignKey(Aliment, on_delete=models.CASCADE)
    menu = models.ForeignKey(Menu, on_delete=models.CASCADE)
    quantite = models.IntegerField(default=0)
    def __str__(self):
        return "({0}:{1})".format(self.quantite, self.aliment)

Formset用来处理('aliment', 'quantite')from Ingredient。这是我的表格:

class MenuModelForm(forms.ModelForm):
    class Meta:
        model = Menu
        fields = ['libelle',]

class IngredientModelForm(forms.ModelForm):
    class Meta:
        model = Ingredient
        fields = ['aliment', 'quantite',]

主要目的是,Menu有几个Aliment通过Ingredient类。使用 javascript,我将Aliment一个列表 (list1) 中的项目动态添加到Menu.Ingredient列表 (list2)。

用户在 list2 中添加项目的唯一方法是单击 list1 的某个“添加按钮”。

问题ModelChoiceField在于包含Aliment数据库中所有实例的选择。

('aliment.id', 'aliment.libelle', 'quantite')我会为每个Ingredient 属于Menu实例的元组管理一种元组。

一方面,我可以在我的Ingredient formset模板中显示,如下所示:

<table>
    {% for item in menu.ingredient %}
        <tr>
            <td>
                <p name="{{ item.aliment.html_name }}" id="{{ fs.aliment.id_for_label }}"
                value="{{ item.aliment.id }}">{{ fs.aliment.libelle }}</p>
            </td>
            <td><input type="number" name="{{ item.quantite.html_name }}" value="{{ item.quantite.value }}" id="{{ item.quantite.id_for_label }}" /></td>
        </tr>
    {% endfor %}
</table>

另一方面,获取迭代Aliment实例的方法是什么?Ingredient formset

我不知道 DjangoForm和 Django 哲学是否是为此而生的。

请您提出一些建议。

谢谢 !

4

1 回答 1

0

当我问问题时,我意识到我很困惑。下次我会尽量简洁。

无论如何,我找到了许多问题的解决方案(也许你会明白我的意思:p)。

我像这样添加了libelle字段IngredientModelForm

class IngredientModelForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        print(kwargs['instance'])
        self.fields['libelle'].initial = kwargs['instance'].aliment.libelle

    class Meta:
        model = Ingredient
        fields = ['aliment', 'quantite',]

    libelle = forms.CharField(max_length=50)

所以我可以访问libelle我的模板中的字段。
在我的视图文件中,我这样做了:

def add_menu(request):
    ingredientFormSet = modelformset_factory(Ingredient, form=IngredientModelForm, fields=('aliment', 'quantite'), extra=0)
    if request.method == 'POST':
        form = MenuForm(request.POST)
        formset = ingredientFormSet(request.POST)
        if form.is_valid() and formset.is_valid():
            ...
    else:
        menu = Menu.objects.all()[0]
        form = MenuModelForm(instance=menu)
        formset = ingredientFormSet(queryset=menu.ingredient_set.all())

因此,对于每个IngredientModelForm实例,其 field 的初始值libelle将是Aliment附加到的实例的值Ingredient

让我们看一下模板:

<form action="" method="POST">
    {{ formset.management_form }}
    <ul>
        {% for fs in formset.forms %}
        <li>
        {{ fs.id.label_from_instance }}
            <span><input type="hidden" name="{{ fs.id.html_name }}" value="{{ fs.id.value }}" id="{{ fs.id.id_for_label }}" /></span>
            <span><input type="hidden" name="{{ fs.aliment.html_name }}" value="{{ fs.aliment.value }}" id="{{ fs.aliment.id_for_label }}" /></span>
            <span>{{ fs.libelle.value }}<input type="hidden" name="{{ fs.libelle.html_name }}" value="{{ fs.libelle.value }}" id="{{ fs.libelle.id_for_label }}" /></span>
            <span><input type="number" name="{{ fs.quantite.html_name }}" value="{{ fs.quantite.value }}" id="{{ fs.quantite.id_for_label }}" /></span>
        </li>
        {% endfor %}
    </ul>
    <input type="submit" value="Ajouter" />
</form>

所以,我可以Aliment用 a显示名称select widget(因为我的Aliment选择是用另一个列表管理的)。

我不知道这对 Django 是否是一个好习惯。

随意提出其他简单的解决方案!:)

于 2018-05-28T18:48:01.917 回答