Я пытаюсь создать сайт, который позволяет пользователям создавать и хранить рецепты. У меня есть модель рецепта, и я использую специальную «сквозную таблицу», чтобы иметь многочисленные ингредиенты для каждого рецепта (каждый ингредиент имеет свой собственный атрибут, такой как количество и единица измерения).
class recipe(models.Model):
recipe_name = models.CharField(max_length=200, unique=True)
description = models.CharField(max_length=200, default='N/A')
ingredients = models.ManyToManyField('ingredient', through='recipe_ingredient', related_name='recipes')
def __str__(self):
return self.recipe_name
class recipe_ingredient(models.Model):
recipe = models.ForeignKey('recipe', related_name='recipe_ingredients', on_delete=models.CASCADE)
ingredient = models.ForeignKey('ingredient', related_name='recipe_ingredients', on_delete=models.CASCADE)
unit = models.ForeignKey('unit', related_name='recipe_ingredients', on_delete=models.CASCADE)
quantity = models.IntegerField()
def __str__(self):
return f'{self.quantity} {self.unit} {self.ingredient}'
class unit(models.Model):
measurement_desc = models.CharField(max_length=50, unique=True)
def __str__(self):
return self.measurement_desc
class ingredient(models.Model):
ingredient_name = models.CharField(max_length=100, unique=True)
def __str__(self):
return self.ingredient_name
Я тогда используя formset_factory, чтобы позволить пользователю динамически добавлять несколько ингредиентов в рецепт.
class RecipeForm(ModelForm):
class Meta:
model = recipe
fields = ['recipe_name', 'description']
def __init__(self, *args, **kwargs):
super(RecipeForm, self).__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_tag = True
self.helper.form_class = 'form-horizontal'
self.helper.label_class = 'col-md-3 create-label'
self.helper.field_class = 'col-md-9'
self.helper.layout = Layout(
Div(
Field('recipe_name'),
Field('description'),
Formset('ingredients'),
HTML("<br>"),
ButtonHolder(Submit('submit', 'save')),
)
)
class IngredientForm(ModelForm):
class Meta:
model = recipe_ingredient
fields = ['quantity', 'unit', 'ingredient']
IngredientFormset = inlineformset_factory(recipe, recipe_ingredient, form=IngredientForm, extra=1, can_delete=True)
Это работает нормально, если я вручную ввожу ингредиенты в базу данных, но если я пытаюсь изменить входные данные для ингредиентов на TextInputs, чтобы разрешить пользователь для создания новых ингредиентов не будет сохранять (из-за того, что эти ингредиенты отсутствуют в базе данных. Это мой обзор:
class CreateRecipe(CreateView):
model = recipe
form_class = RecipeForm
template_name = 'mealplanner/recipe_create.html'
def get_context_data(self, **kwargs):
data = super(CreateRecipe, self).get_context_data(**kwargs)
if self.request.POST:
data['ingredients'] = IngredientFormset(self.request.POST)
else:
data['ingredients'] = IngredientFormset()
return data
def form_valid(self, form):
context = self.get_context_data()
ingredients = context['ingredients']
with transaction.atomic():
self.object = form.save()
if ingredients.is_valid():
ingredients.instance = self.object
ingredients.save()
return super(CreateRecipe, self).form_valid(form)
def get_success_url(self):
return reverse_lazy('recipe-detail', kwargs={'pk': self.object.pk})
Я ошибаюсь или есть способ получить django сохранить новые ингредиенты в базе данных, когда пользователь создает новые рецепты?