Search code examples
djangodjango-formsdjango-templates

Filling the FormMixin form


Is it possible to populate FormMixin form data without passing the form variable to the template? I have a template, but I don't understand how to create a form with Django, so I just specify the name attribute in the template. The form is created, everything is fine, I override the method
get_initial() method, but the form is not filled out Is it possible to do this or do I need to pass the form variable?

class CommentEditView(View, FormMixin):
    form_class = EditCommentForm

    def get_initial(self):
        initial = super().get_initial()
        comment = get_object_or_404(Comment, pk=15)
        
        initial['review_text'] = comment.review_text
        initial['grade'] = comment.grade

        return initial

    def get(self, request, comment_id):
        return render(request, 'catalog/review-edit.html')
class EditCommentForm(ModelForm):
    class Meta:
        model = Comment
        fields = ['review_text', 'grade']
<form method="POST">
                    {% csrf_token %}
                    <textarea class="product-detail-reviews-textarea" name="review_text" id="id_review_text"></textarea>
                    {% for error in form.review_text.errors %}
                        <p class="product-detail-reviews-error">* {{ error }} </p>
                    {% endfor %}
                    <div class="product-detail-reviews-row">
                        <div class="product-detail-reviews-stars">
                            <p>Stars:</p>
                            <div class="rating-area">
                                <input type="radio" id="id_grade_five" name="grade" value="5">
                                <label for="id_grade_five" title="Star «5»"></label>    
                                <input type="radio" id="id_grade_four" name="grade" value="4">
                                <label for="id_grade_four" title="Star «4»"></label>    
                                <input type="radio" id="id_grade_three" name="grade" value="3">
                                <label for="id_grade_three" title="Star «3»"></label>  
                                <input type="radio" id="id_grade_two" name="grade" value="2">
                                <label for="id_grade_two" title="Star «2»"></label>    
                                <input type="radio" id="id_grade_one" name="grade" value="1">
                                <label for="id_grade_one" title="Star «1»"></label>
                            </div>
                        </div>
                        <button type="submit" class="product-detail-reviews-link">Confirm</a>
                    </div>
                    {% for error in form.grade.errors %}
                        <p class="product-detail-reviews-error">*{{ error }} </p>
                    {% endfor %}
        </form>

Overridden the method get_initial()


Solution

  • You don't pass the form to the context, that is the problem. Don't override .get(…): the FormMixin will add the item to a context yes, but by overriding the .get(…) method and just rendering a template, it will never even built the context.

    You can let the TemplateView do the work for you: this will generate the context, and then render the template:

    from django.views.generic import TemplateView
    
    
    class CommentEditView(FormMixin, TemplateView):
        form_class = EditCommentForm
        template_name = 'catalog/review-edit.html'
    
        def get_initial(self):
            initial = super().get_initial()
            comment = get_object_or_404(Comment, pk=15)
    
            initial['review_text'] = comment.review_text
            initial['grade'] = comment.grade
    
            return initial
    
        # no def get(self, request, comment_id)

    As for the template, you then load data from the form into the template, for example with:

    <textarea class="product-detail-reviews-textarea" name="review_text" id="id_review_text">
        {{ form.review_text.widget.value }}
    </textarea>