0

Django をよりよく理解し、遭遇する可能性のある同様の問題にもっと簡単に対処できるように、幅広い質問をしようと思いました。私が抱えている特定の問題は、フォームを正しくレンダリングする最初のフォームセット コードを作成したことですが、投稿されたときに新しいオブジェクトが作成されないことです。

フォームが投稿されたことをサーバーから確認できます。エラーは発生しませんが、データベースにデータが追加されていません (django admin および manage.py シェルから確認)。manage.py シェルに投稿された内容を読み取ることは可能でしょうか? フォームがデータを正しく投稿し、ビューで受信されたかどうかを確認できるようにしたいと思います。次に、データが正しく投稿されていないか、ビューがデータを正しく処理していない理由を確認できます。

特定の問題については、ウィザードの 1 人が見つけられる単純な初心者エラーの場合に備えて、以下にコードを配置します。私はこのチュートリアルに従って、自分の目的に合わせて適応しようとしました。

モデル.py

class Chunk(models.Model):
    name = models.CharField(max_length=250)
    text = models.CharField(max_length=500)
    images = models.FileField()
    question = models.CharField(max_length=250)
    expected_completion_time = models.IntegerField(default=1)
    keywords = models.CharField(max_length=250, blank=True, null=True)
    topic = models.CharField(max_length=250, blank=True, null=True)
    course = models.CharField(max_length=250, blank=True, null=True)
    is_flagged = models.BooleanField(default=False)

    def get_absolute_url(self):
        return reverse('detail', kwargs={'pk':self.pk})

    def __str__(self):
        return self.name


class Concept(Chunk):
    application = models.CharField(max_length=500)

    @property
    def mode(self):
        return "concept"


class Subconcepts(models.Model):
    subconcept = models.CharField(max_length=500)
    concept = models.ForeignKey(Concept, on_delete=models.CASCADE)

    def __str__(self):
        return self.concept.name + ' - Subconcept'

フォーム.py

class ConceptForm(forms.ModelForm):
    # Form for creating Concept objects
    class Meta:
        model = Concept
        fields = ['application', 'name', 'text', 'images', 'question', 'expected_completion_time', 'keywords', 'topic', 'course']


class SubconceptForm(forms.ModelForm):
    # Form for creating Subconcept objects which are linked by ManyToOne fields to Concept objects
    class Meta:
        model = Subconcepts
        fields = ['subconcept']  # Concept field excluded as will be set in view on form submission


class BaseSubconceptFormset(BaseFormSet):
    def clean(self):
        # Validate that all subconcepts are unique
        if any(self.errors):
            return
        subconcepts = []
        duplicates = False

        for form in self.forms:
            if form.cleaned_data:
                subconcept = form.cleaned_data('subconcept')

                if subconcept:
                    if subconcept in subconcepts:
                        duplicates = True
                    subconcepts.append(subconcept)

                if duplicates:
                    raise forms.ValidationError(
                        'Each key feature must be unique',
                        code='duplicate_subconcept'
                    )

ビュー.py

def testformsets(request):

    # Forms for creating a concept with appropriate subconcepts
    SubconceptFormset = formset_factory(SubconceptForm, formset=BaseSubconceptFormset)

    if request.method == 'POST':
        concept_form = ConceptForm(request.POST)
        subconcept_formset = SubconceptFormset(request.POST)

        if concept_form.is_valid() and subconcept_formset.is_valid():
            concept = concept_form.save()

            new_subconcepts = []

            for subconcept_form in subconcept_formset:
                subconcept = subconcept_form.cleaned_data.get('subconcept')
                new_subconcepts.append(Subconcepts(subconcept=subconcept, concept=concept))

            try:
                with transaction.atomic():
                    # Add all new subconcepts at once
                    Subconcepts.objects.bulk_create(new_subconcepts)

                    # And notify our users that it worked
                    messages.success(request, 'You have added new material')

            except IntegrityError:  # If the transaction failed
                messages.error(request, 'There was an error saving your concept.')
                return redirect('pomodoro/index.html')

    else:
        concept_form = ConceptForm()
        subconcept_formset = SubconceptFormset()

    context = {
        'concept_form': concept_form,
        'subconcept_formset': subconcept_formset
    }
    return render(request, 'pomodoro/formset_test.html', context)
4

1 に答える 1