forms.py 中的 Django QuestionForm 不在 questions.html 中创建实例

问题描述 投票:0回答:1

我在 forms.py 中有一个 QuestionForm ,旨在创建 Question 模型的实例以显示在 questions.html 中。但是,当我提交表单时,我会被重定向回ask_question.html,而不会创建任何新实例。

调试步骤:

1.创建管理面板

我可以通过 Django 管理面板创建问题模型的实例,这是当前唯一显示的实例。

2.前端提交

我尝试使用前端创建 Question 模型的实例,并且没有出现错误消息。但是,questions.html 模板中没有出现 Question 模型的实例。

3.我检查了
QuestionForm
 中的 
forms.py

它似乎按预期工作。

    class QuestionForm(forms.ModelForm):
        subject = forms.CharField(max_length=100, required=True, help_text='Enter a subject line for your question.')
        body = forms.CharField(widget=forms.Textarea, max_length=10000, required=True, help_text='Enter the main body of your question.')
        teacher_standard = forms.MultipleChoiceField(
            required=False,
            widget=forms.CheckboxSelectMultiple,
            choices=[(1, 'High Expectations'), (2, 'Promoting Progress'), (3, 'Subject Knowledge'), (4, 'Planning'), (5, 'Differentiation'), (6, 'Assessment'), (7, 'Behaviour Management'), (8, 'Professionalism')],
            help_text='Select the standard(s) for which you are asking the question.'
        )
        class Meta:
            model = Question  
            fields = ['subject', 'body', 'teacher_standard']  

4.检查
Question
 中的 
models.py

模型

它似乎按预期工作。

class Question(models.Model):
    title = models.CharField(max_length=200, unique=True)
    slug = models.SlugField(max_length=200, unique=True) 
    author = models.ForeignKey(User, on_delete=models.CASCADE, related_name="question_posts")
    featured_image = CloudinaryField('image', default='placeholder')
    excerpt = models.TextField(blank=True)
    updated_on = models.DateTimeField(auto_now=True)
    content = models.TextField()
    created_on = models.DateTimeField(auto_now_add=True)
    status = models.IntegerField(choices=STATUS, default=0)
    upvotes = models.ManyToManyField(User, related_name='questionpost_upvote', blank=True)
    downvotes = models.ManyToManyField(User, related_name='questionpost_downvote', blank=True)
    subject = models.CharField(max_length=100, unique=True)
    body = models.TextField
    standards = models.ManyToManyField(TeachingStandardTag, related_name='questions', blank=True)
    answercount = models.IntegerField(default=0)
    views = models.IntegerField(default=0)

    class Meta: 
        ordering = ["-created_on"]

    def __str__(self):
        return self.subject

    def number_of_upvotes(self):
        return self.upvotes.count()

5.检查
ask_question.html
模板

它似乎按预期工作。

{% extends "base.html" %}
{% load static %}

{% block content %}
<div class="container">
    <h2>Ask a Question</h2>
    <form method="post" action="">
        {% csrf_token %}
        <div class="form-group">
            <label for="subject">Subject:</label>
            <input type="text" class="form-control" id="subject" name="subject" placeholder="Enter subject line">
        </div>
        <div class="form-group">
            <label for="body">Question:</label>
            <textarea class="form-control" id="body" name="body" rows="5" placeholder="Enter the main body of your question"></textarea>
        </div>
        <div class="form-group">
            <label for="teacher_standard">Teacher Standard:</label>
            {% for value, text in form.teacher_standard.field.choices %}
            <div class="form-check">
                <input class="form-check-input" type="checkbox" name="teacher_standard" id="teacher_standard_{{value}}" value="{{value}}">
                <label class="form-check-label" for="teacher_standard_{{value}}">
                    {{text}}
                </label>
            </div>
        {% endfor %}
        </div>
        <button type="submit" class="btn btn-primary">Submit</button>
    </form>
</div>
{% endblock %}

6.在
views.py

中创建两个不同的表单验证

这将追溯问题。然而,两者似乎都没有改变任何事情,提交表格后,

questions.html
中没有出现问题的实例。

class QuestionCreate(generic.CreateView): # this class will create a question
    model = Question
    template_name = "ask_question.html" # template for the create question pageddd
    fields = ["title", "slug", "author"]

    def ask_question(request): # this function will ask a question
        if request.method == 'POST':
            form = QuestionForm(request.POST)
            if form.is_valid():
                question = form.save(commit=False)
                question.author = request.user  # assuming you have user authentication
                question.save()
                return redirect('questions')  # or wherever you want to redirect after successful submission
            else:
                print(form.errors)  # Helps debug what's wrong with the form
        else:
            form = QuestionForm()
        return render(request, 'ask_question.html', {'form': form})

    def form_valid(self, form):
        # This method is called when valid form data has been POSTed. It should return an HttpResponse.
        form.instance.author = self.request.user  # Assign the author to the user submitting the form
        return super().form_valid(form)

[...]

    def question(self, request, *args, **kwargs): #renamed from post to postquestion
        # Create a form instance and populate it with data from the request
        form = QuestionForm(request.POST)
        if form.is_valid():
            # Handle the form submission and create a new Question instance
            new_question = Question.objects.create(
                title=form.cleaned_data['subject'],
                content=form.cleaned_data['body'],
                author=request.user,
                slug=form.cleaned_data['subject'],
                status=1
            )
            new_question.save()
        return render(request, 'ask_question.html', {'form': form})

7.简化
QuestionCreate
 中的 
views.py

然而,它似乎没有改变任何东西,提交表单后似乎没有创建任何问题实例。

class QuestionCreate(generic.CreateView): # this class will create a question
    model = Question
    form_class = QuestionForm  # Use the custom form class
    template_name = "ask_question.html"

    def form_valid(self, form):
        form.instance.author = self.request.user
        # Generate a slug from the subject or use any other field as necessary
        form.instance.slug = form.cleaned_data['subject'].replace(' ', '-').lower()
        return super(QuestionCreate, self).form_valid(form)

    def get_success_url(self):
        # Redirect to the 'questions' page after form submission
        return reverse_lazy('questions')
  1. 使用 {{ form.as_p }}
     简化views.py 中的 
    ask_question.html
{% extends "base.html" %}
{% load static %}

{% block content %}
<div class="container">
    <h2>Ask a Question</h2>
    <form method="post" action="">
        {% csrf_token %}
        {{ form.as_p }} <!-- This will render all the fields using the form instance -->
        <button type="submit" class="btn btn-primary">Submit</button>
    </form>
</div>
{% endblock %}

这会导致在提交表单时出现新的错误消息:

IntegrityError at /ask_question/
duplicate key value violates unique constraint "blog_question_title_key"
DETAIL:  Key (title)=() already exists.

9.检查了 Javascript 控制台

没有错误消息。

10.更新了
QuestionForm
中的
forms.py
类以包含
title

这修复了步骤 8 中的错误消息,但不会创建明显的实例。

class QuestionForm(forms.ModelForm):
    subject = forms.CharField(max_length=100, required=True, help_text='Enter a subject line for your question.')
    body = forms.CharField(widget=forms.Textarea, max_length=10000, required=True, help_text='Enter the main body of your question.')
    teacher_standard = forms.MultipleChoiceField(
        required=False,
        widget=forms.CheckboxSelectMultiple,
        choices=[(1, 'High Expectations'), (2, 'Promoting Progress'), (3, 'Subject Knowledge'), (4, 'Planning'), (5, 'Differentiation'), (6, 'Assessment'), (7, 'Behaviour Management'), (8, 'Professionalism')],
        help_text='Select the standard(s) for which you are asking the question.'
    )

    class Meta:
        """
        the Meta class is used to specify the model to which the form is associated and the fields from the model you want the form to include.
        """
        model = Question  # Specifies the model in models.py associated with this form
        fields = ['title', 'subject', 'body', 'teacher_standard']  # The fields from the model you want the form to include
django django-models django-forms
1个回答
0
投票

下面我发布了解决问题的步骤。

检查后我很快意识到,在第 6 步或第 7 步之间,我能够在后端存储问题。

调试步骤继续

11. Django 管理员评论

我仔细检查了 Django Admin,看看后端是否创建了任何测试表单。他们有!然而,它们并没有出现在前端。我希望他们出现在

questions.html

    test3 (does not appear in questions.html)   subject3    Draft   Dec. 22, 2023, 12:21 p.m.
    testpost1   testpost1   Published   Dec. 18, 2023, 6:57 p.m.

12.检查详细信息以发现草稿/发布状态

经过检查,我可以看到 test3 是草稿,这可能可以解释为什么它没有上传。当我将状态更改为“已发布”时,它确实出现在

questions.html
中。因此,现在的问题似乎是表单不是作为已发布的表单提交,而是作为草稿提交。

13.调整
form_valid
 中的 
views.py

方法

我试图确保在提交表单并创建问题实例时将问题模型的状态字段设置为“已发布”。我需要调整我的表单或视图逻辑以设置正确的状态。

首先,我调整了

form_valid
中的
views.py
方法,将表单有效时的状态设置为1(已发布)。

def form_valid(self, form):
    form.instance.author = self.request.user
    form.instance.slug = form.cleaned_data['subject'].replace(' ', '-').lower()
    form.instance.status = 1  # Set the status to "Published". Assuming '1' corresponds to "Published" in your STATUS choices
    return super().form_valid(form)

这成功创建了一个已发布的实例,该实例出现在

questions.html

的前端
© www.soinside.com 2019 - 2024. All rights reserved.