Сохранение данных динамической формы django

Спасибо, что прочитали этот пост и предложили мне помощь.

Я новичок в Django и работаю над веб-сайтом для аборигенных регионов, чтобы записывать их жизни. Пользователи могут создавать страницы и публиковать содержимое. Перед тем, как создать страницу, им необходимо указать количество сезонов, которое они хотят записать. Веб-сайт будет основан на количестве сезонов для динамического создания текстовых полей.

В настоящее время я могу динамически создавать текстовые поля, но у меня проблемы с сохранением данных. Я долго пытался решить эту проблему, но все равно застрял здесь. Я получил ошибку: объект SeasonalTextForm не имеет атрибута instance.

статья, которой я следил, когда реализовал динамическую форму: 1https://jacobian.org/writing/dynamic-form-generation/ [2] https://www.caktusgroup.com/blog/2018/05/07/creating-dynamic-forms-django/

Вот сообщение об ошибке (изображение можно прикрепить только как ссылку): Ошибка атрибута: объект SeasonalTextForm не имеет атрибута instance

Вот мой model.py

class PageComponent(models.Model):
    componentName=models.CharField(max_length=50,null=True, verbose_name = "Name")
    type = models.ForeignKey(Type, on_delete=models.CASCADE)
    user = models.ForeignKey(AS_User, on_delete=models.CASCADE, editable=False)
    page = models.ForeignKey(CommunityPage, on_delete=models.CASCADE, editable=False)
    STATUS = (
        ('a', 'Activated'),
        ('d', 'Deactivated'),
    )

    componentStatus=models.CharField(
        max_length=1,
        choices=STATUS,
        blank=False,
        default='d',
        help_text='the current status of the page component', editable=False
    )

    textContent=models.TextField(max_length=10000, help_text = "Enter a description for your component", null=True, blank=True)
    photoContent=models.ImageField(upload_to=component_directory_path, null=True, blank=True, verbose_name = "Photo")
    # videoContent=models.VideoField(upload_to=component_directory_path, null=True, blank=True, verbose_name = "Video")

class PageComponent_SeasonalText(models.Model):
    pageStextComponent = models.ForeignKey(PageComponent, on_delete=models.CASCADE)
    seasonalText = models.CharField(max_length=10001)

Вот мой form.py:

class SeasonalTextForm(forms.Form):
    componentName = forms.CharField(label=_('Enter title'),max_length=40)

    def __init__(self, *args, **kwargs):
        seasonTexts = kwargs.pop('extra')
        # super(SeasonalTextForm, self).__init__(*args, **kwargs)
        super(SeasonalTextForm, self).__init__(*args, **kwargs)
        # seasonTexts = PageComponent_SeasonalText.objects.filter(pageStextComponent = pageStextComponent)

        for i in range(seasonTexts):
            field_name = 'seasonText_%s' % (i,)
            self.fields[field_name] = forms.CharField(widget=forms.Textarea(attrs = {'rows':10, 'cols':51}))
        #set field label as placeholder for every field
        for field in self.fields.values():
            field.widget.attrs["placeholder"] = field.label
        # field_name = 'seasonText_%s' % (i+1,)
        # self.fields[field_name] = forms.CharField(widget=forms.Textarea(attrs = {'rows':10, 'cols':51}))
        # self.fields[field_name] = ""

    def clean(self):
        seasonTexts = set()
        i = 0
        field_name = 'seasonText_%s'% (i,)
        while self.cleaned_data.get(field_name):
            seasonText = self.cleaned_data[field_name]
            if seasonText in seasonTexts:
                self.add_error(field_name, 'Duplicate')
            else:
                seasonTexts.add(seasonText)
            i += 1
            field_name='seasonText_%s' % (i,)
        self.cleaned_data["seasonTexts"] = seasonTexts

    def save(self):
        PageComponent = self.instance
        PageComponent.save()
        PageComponent.componentName = self.cleaned_data["componentName"]
        # pageStextComponent.seasonText_set.all().delete()
        for seasonalText in self.cleaned_data["seasonTexts"]:
            PageComponent_SeasonalText.objects.create(
                pageStextComponent = PageComponent.pageStextComponent,
                seasonalText = seasonalText,
            )

    def get_seasonText_fields(self):
        for field_name in self.fields:
            if field_name.startswith('seasonText'):
                yield self[field_name]

Вот мой view.py:

def SeasonalText(request, page_id, id):
    page = get_object_or_404(CommunityPage, pk=page_id)
    as_user = get_object_or_404(AS_User, pk=id)
    # s_component = get_object_or_404(PageComponent, pk=cid)
    numOfSeasons = page.numSeasons
    form = SeasonalTextForm(request.POST, extra=numOfSeasons)
    # sTexts = PageComponent_SeasonalText.objects.filter(pageComponent_id=s_component)
    # form = SeasonalTextForm(request.POST, extra=sTexts)
    if request.method == "POST":
        if form.is_valid():
            form.save()
            # my_user = AS_User.objects.get(id=request.user.id)
            # my_type = Type.objects.get(id=4)
            # PageComponent.user = my_user
            # PageComponent.page = page
            # PageComponent.type = my_type
            # PageComponent.save()
            return HttpResponseRedirect(reverse('page', kwargs = {'page_id':page_id}))
    else:
        form = SeasonalTextForm(extra=numOfSeasons)
    return render(request, 'communityPages/Stext_component.html', {'form':form, 'page':page, 'id':as_user})

Это неправильный подход. Поскольку вы хотите создать несколько экземпляров, вам следует использовать набор форм, который позаботится обо всем этом за вас.

Daniel Roseman 13.09.2018 10:56

@DanielRoseman привет, Даниэль, что, если я не хочу создавать несколько экземпляров? В чем смысл создания экземпляров? Я сделал это потому, что это было сделано в примере, и я не могу найти альтернативный способ изменить это. Спасибо за ваш быстрый ответ.

Ken Choi 13.09.2018 11:02

Какие? Я имею в виду экземпляры PageComponent_SeasonalText. Создание ряда из них - это точно, что вы пытаетесь сделать. Об этом позаботится набор моделей. См. docs.djangoproject.com/en/2.0/topics/forms/modelforms/…

Daniel Roseman 13.09.2018 11:05

Здравствуйте, ken-choi, попробуйте использовать набор форм, если хотите, я могу опубликовать ваш ответ, но сначала вы должны прочитать документ для использования набора форм.

Mbambadev 13.09.2018 13:22

@rakwen Я прочитал документ и попробовал два примера в Интернете, но все еще не могу применить принцип в моем случае. Было бы здорово, если бы у вас было время помочь мне в этом. Спасибо.

Ken Choi 13.09.2018 15:02

У меня есть время ! Но объясните мне четко, что вы хотите сделать, шаг за шагом ...

Mbambadev 13.09.2018 15:04

@rakwen, я следую этому руководству: medium.com/@adandan01/…. В настоящее время у меня есть готовые модели model.py и form.py. Но я не уверен, как использовать view.py, поскольку в учебнике используются многие функции, с которыми я не знаком.

Ken Choi 13.09.2018 15:13

@rakwen, я тоже хочу знать, нужно ли мне использовать inlineformset_factory? в учебнике профиль и члены семьи находятся в зависимых отношениях. В моем случае так же. Вот почему я выбрал этот учебник, но, похоже, он не реализуется обычным образом.

Ken Choi 13.09.2018 15:18

Попробуйте этот учебник: whoisnicoleharris.com/2015/01/06/… - тот же метод, но более подробно объяснен

Mbambadev 13.09.2018 15:18

@rakwen, спасибо за ссылку. Я его ищу.

Ken Choi 13.09.2018 15:19

Используйте это: whoisnicoleharris.com/2015/01/06/…

Mbambadev 13.09.2018 15:22

@rakwen большое спасибо за вашу помощь! Я добираюсь туда. Могу я спросить, как передать значение extra в наборе форм? Я хочу, чтобы значение extra было динамическим, чем взаимодействие с кнопкой. Вот код моего набора форм: SeasonalTextFormSet = formset_factory (SeasonalTextForm, extra = 1)

Ken Choi 14.09.2018 01:42

Извините, я не подключаюсь. Если я понимаю, что вы хотите динамически изменить дополнительные параметры набора форм? Это верно ?

Mbambadev 14.09.2018 14:53

да. это то, что я хочу. не изменяется с помощью кнопки добавления / удаления пользовательского интерфейса, а по значению, полученному из другого класса. @ rakwen

Ken Choi 14.09.2018 15:12
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
14
790
0

Другие вопросы по теме