Другой способ управления экземпляром Django Model из ModelChoiceField в форме
Я не уверен, если это возможно. Я пытаюсь использовать Django (2.0) Form
а также Formset
на вид. Вот мои модели:
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')
от 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
итерация?
Я не знаю, если Джанго Form
и философия Джанго создана для этого.
Не могли бы вы сделать несколько предложений, пожалуйста.
Спасибо!
1 ответ
Я понял, что смутился, задавая вопрос. Я постараюсь быть более кратким в следующий раз.
Во всяком случае, я нашел решение многих проблем (может быть, вы поймете, что я имел в виду: р).
я добавил 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
Например, его начальное значение для 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
с select widget
(потому что мой Aliment
выбор осуществляется с помощью другого списка).
Я не знаю, хорошая ли это практика для Джанго.
Не стесняйтесь предложить другое простое решение!:)