Regis Santos
Regis Santos

Reputation: 3749

How to use context with class in CreateView in django?

How to use context with class in CreateView in django?

Before i have:

#views.py
from django.views.generic import CreateView
from cars.models import *

def CreateCar(CreateView):
    info_sended = False
    if request.method == 'POST':
        form = FormCar(request.POST, request.FILES)
        if form.is_valid():
            info_sended = True
            form.save()
    else:
        form = FormCar()
    ctx = {'form': form, 'info_sended':info_sended}
    return render_to_response("create_car.html", ctx,
        context_instance=RequestContext(request))

Now, a have, and try:

class CreateCar(CreateView):
    info_sended = False
    template_name = 'create_car.html'
    model = Car
    success_url = 'create_car' #urls name

    def form_valid(self, form):
        info_sended = True
        ctx = {'form': form, 'info_sended':info_sended}
        return super(CreateCar, self).form_valid(form)

My html page is:

<!-- create_car.html -->
{% extends 'base.html' %}

{% block content %}

{% if info_sended %}
    <p>Data saved successfully</p>
    <p><a href="{% url 'list_cars' %}">Show List</a></p>
{% else %}
    <form class="form-horizontal" action="" method="post">
        {% csrf_token %}
        {% include "form.html" %}
        <div class="col-md-offset-1">
            <button class="btn btn-primary" type="submit">Add</button>
        </div>
    </form>
{% endif %}

{% endblock %}

Upvotes: 7

Views: 15449

Answers (3)

Anthony Petrillo
Anthony Petrillo

Reputation: 505

Since your are creating a new instance of a Car, there is no context for get_context_data because there is no object yet. I didn't test using Mixin to get the context from another class as suggested above, but that seems reasonable. However, if I can assume you want to use the basic CreateView, UpdateView and DeleteView, then I solved this by assuming I will have no context for CreateView. Then in my template I used an if to make the decision, such as:

<form method="post">{% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value={% if not buttonword %}Save{% else %}{{ buttonword }}{% endif %}>
</form>

In DeleteView I include:

context['buttonword'] = 'Delete'

In UpdateView I include:

context['buttonword'] = 'Update'

As I said, I do not set buttonword in CreateView. Hence, when the template logic is done, if buttonword is assigned, the word in it shows up in the button, otherwise Save shows up on the button.

Upvotes: 0

Rohan
Rohan

Reputation: 53326

You should define get_context_data() method in your class view. Update your code as

from django.shortcuts import render

class CreateCar(CreateView):
    info_sended = False
    template_name = 'create_car.html'
    model = Car
    success_url = 'create_car' #urls name

    def form_valid(self, form):
        self.info_sended = True
        # Instead of return this HttpResponseRedirect, return an 
        #  new rendered page
        super(CreateCar, self).form_valid(form)
        return render(self.request, self.template_name,
                      self.get_context_data(form=form))


    def get_context_data(self, **kwargs):
        ctx = super(CreateCar, self).get_context_data(**kwargs)
        ctx['info_sended'] = self.info_sended
        return ctx

Upvotes: 14

Victor Castillo Torres
Victor Castillo Torres

Reputation: 10811

You have to use get_context_data

class CreateCar(CreateView):
    info_sended = False
    template_name = 'create_car.html'
    model = Car
    success_url = 'create_car' #urls name

    def form_valid(self, form):
        self.info_sended = True
        return super(CreateCar, self).form_valid(form)

    def get_context_data(self, **kwargs):
        ctx = super(CreateCar, self).get_context_data(**kwargs)
        ctx['info_sended'] = self.info_sended
        return ctx

If you see the django source CreateView inherits from BaseCreateView this one inherits from ModelFormMixin in turn this one inherits from FormMixin and this one inherits from ContextMixin and the only method this one defines is get_context_data. Hope this helps you.

PD: This may be a bit confusing for better understanding of inheritance in Python feel free of read this article about MRO.

Upvotes: 1

Related Questions