Исходные данные для Django встроенный Formsets

Я соединил форму для сохранения рецепта. Это использует форму и встроенный formset. У меня есть пользователи с текстовыми файлами, содержащими рецепты, и они хотели бы вырезать и вставить данные для создания записи легче. Я разработал, как заполнить часть формы после обработки входа необработанного текста, но я не могу выяснить, как заполнить встроенный formset.

Кажется, что решение почти записано здесь: http://code.djangoproject.com/ticket/12213, но я не могу вполне соединить части.

Мои модели:

#models.py

from django.db import models

class Ingredient(models.Model):
    title = models.CharField(max_length=100, unique=True)

    class Meta:
        ordering = ['title']

    def __unicode__(self):
        return self.title

    def get_absolute_url(self):
        return self.id

class Recipe(models.Model):
    title = models.CharField(max_length=255)
    description = models.TextField(blank=True)
    directions = models.TextField()

    class Meta:
        ordering = ['title']

    def __unicode__(self):
        return self.id

    def get_absolute_url(self):
        return "/recipes/%s/" % self.id

class UnitOfMeasure(models.Model):
    title = models.CharField(max_length=10, unique=True)

    class Meta:
        ordering = ['title']

    def __unicode__(self):
        return self.title

    def get_absolute_url(self):
        return self.id

class RecipeIngredient(models.Model):
    quantity = models.DecimalField(max_digits=5, decimal_places=3)
    unit_of_measure = models.ForeignKey(UnitOfMeasure)
    ingredient = models.ForeignKey(Ingredient)
    recipe = models.ForeignKey(Recipe)

    def __unicode__(self):
        return self.id

Форма рецепта создается с помощью ModelForm:

class AddRecipeForm(ModelForm):
    class Meta:
        model = Recipe
        extra = 0

И соответствующие нормы в представлении (звонит для парсинга исходных данных формы, удалены):

def raw_text(request):
    if request.method == 'POST':

    ...    

        form_data = {'title': title,
                    'description': description,
                    'directions': directions,
                    }

        form = AddRecipeForm(form_data)

        #the count variable represents the number of RecipeIngredients
        FormSet = inlineformset_factory(Recipe, RecipeIngredient, 
                         extra=count, can_delete=False)
        formset = FormSet()

        return render_to_response('recipes/form_recipe.html', {
                'form': form,
                'formset': formset,
                })

    else:
        pass

    return render_to_response('recipes/form_raw_text.html', {})

С FormSet () пустой как выше я могу успешно запустить страницу. Я попробовал несколько способов подать formset количество, unit_of_measure и компоненты, включая которые я определил:

  • при установке исходных данных, но это не работает на встроенный formsets
  • при передаче словаря, но это генерирует ошибки формы управления
  • играемый вокруг с init, но я немного вне моей глубины там

Любые предложения значительно ценятся.

8
задан Serjik 19 December 2015 в 11:35
поделиться

1 ответ

Моим первым советом было бы выбрать простой выход: сохранить Recipe и RecipeIngredient s, а затем использовать полученный Recipe в качестве вашего экземпляра при создании FormSet . Вы можете захотеть добавить к своим рецептам логическое поле «проверено», чтобы указать, были ли наборы форм затем одобрены пользователем.

Однако, если вы не хотите идти по этому пути по какой-либо причине, вы сможете заполнить свои наборы форм следующим образом:

Мы предполагаем, что вы разобрали текстовые данные на ингредиенты рецепта, и есть список словарей, подобных этому:

recipe_ingredients = [
    {
        'ingredient': 2,
        'quantity': 7,
        'unit': 1
    },
    {
        'ingredient': 3,
        'quantity': 5,
        'unit': 2
    },
]

Числа в полях «ингредиент» и «единица измерения» являются значениями первичного ключа для соответствующих ингредиентов и объектов единиц измерения. Я предполагаю, что вы уже сформулировали какой-то способ сопоставления текста с ингредиентами в вашей базе данных или создания новых.

Затем вы можете сделать:

RecipeFormset = inlineformset_factory(
    Recipe,
    RecipeIngredient,
    extra=len(recipe_ingredients),
    can_delete=False)
formset = RecipeFormset()

for subform, data in zip(formset.forms, recipe_ingredients):
    subform.initial = data

return render_to_response('recipes/form_recipe.html', {
     'form': form,
     'formset': formset,
     })

Это устанавливает свойство initial каждой формы в наборе форм в словарь из вашего списка recipe_ingredients . Мне кажется, это работает с точки зрения отображения набора форм, но я еще не пробовал сохранять.

20
ответ дан 5 December 2019 в 07:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: