1

EDIT 2: Complete traceback with the line context = super(ComecandoView, self).get_context_data(**kwargs) uncommented. If I change this line to context = {} I don't get any errors, but still can't use the user's variable.

  1. response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "C:\Users\gabriel\PycharmProjects\django-solo-testes\wvevn\lib\site-packages\django\views\generic\base.py" in view 68. return self.dispatch(request, *args, **kwargs)

File "C:\Users\gabriel\PycharmProjects\django-solo-testes\wvevn\lib\site-packages\django\views\generic\base.py" in dispatch 88. return handler(request, *args, **kwargs)

File "C:\Users\gabriel\PycharmProjects\django-solo-testes\wvevn\lib\site-packages\django\views\generic\edit.py" in get 174. return self.render_to_response(self.get_context_data())

File "C:\Users\gabriel\PycharmProjects\django-solo-testes\papaBelini\core\views.py" in get_context_data 107. context = super(ComecandoView, self).get_context_data(**kwargs)

File "C:\Users\gabriel\PycharmProjects\django-solo-testes\wvevn\lib\site-packages\django\views\generic\edit.py" in get_context_data 93. kwargs['form'] = self.get_form()

File "C:\Users\gabriel\PycharmProjects\django-solo-testes\wvevn\lib\site-packages\django\views\generic\edit.py" in get_form 45. return form_class(**self.get_form_kwargs())

Exception Type: TypeError at /comecando Exception Value: 'NoneType' object is not callable

EDIT: I did some changes as asked and updated my post but it still doesn't work. The error I'm getting now is saying that NoneType object is not callable on the line context = super(ComecandoView, self).get_context_data(**kwargs). If I comment this and add context {} the code works fine but it's not running the function form_valid, I've tried to print stuff inside that function into the terminal and nothing happens, but the code still doing what it's supposed to after the changes, apart from not retreiving the user's input. I've also tried changing the form method to post but no luck.

What I want to do: I want to update a graph created in a view according to the user's input (i.e., user types the date range for the graph and the template generate a new graph with updated values).

I have a django view which already creates the graph with pre-defined values.

Check the code below, it works fine.

views.py

class ComecandoView(FormView):
    template_name = 'comecando.html'
    form = GraphForm
    def form_valid(self, form):
        # store the user input here. These variables you can access then in your get_context_data method.
        print('Hi') # Doesnt get called
        self.q=form.cleaned_data['q']
        return super(ComecandoView, self).form_valid(form)

    def get_context_data(self, **kwargs):
        #context = super(ComecandoView, self).get_context_data(**kwargs) # Commented this.
        context = {} # ADDED THIS
        lista_precos = []
        lista_datas = []
        for variacao in range(10500):
            lista_precos.append(rjson['dataset']['data'][variacao][4])
            lista_datas.append(rjson['dataset']['data'][variacao][0])
        # Create a trace
        trace = go.Scatter(
            y = lista_precos,
            x = lista_datas
        )
        data = [trace]
        fig = go.Figure(data=data)
        div = opy.plot(fig, auto_open=False, output_type='div')
        context['graph'] = div
        return context

template.html (comecando.html)

{% extends 'base.html' %}
{% block container %}
<form method="get">
        <input type="text" name="q">
        <input type="submit" value="Search">
    </form> 

</div>
  {% if graph %}
  <div class="row">
    <div class="col s12">
        {{ graph|safe }}
    </div>
  </div>
{% endif %}
{% endblock %}

forms.py

from django import forms
class GraphForm(forms.Form):
    name = forms.CharField()
    message = forms.CharField(widget=forms.Textarea)
    def send_email(self):
        pass

What I want is for the user to be able to select a value from a combobox for example or type a value into a text field and after he clicks a button the value he typed will be available in my view so that I'll be able to generate a new graph with new values.

What I've tried:

views.py

I added this method inside my class based view but didn't output as expected, I was only able to use the value of the form 'q' inside the get function and also, the graph wasn't generated as it previously were.

def get(self, request, *args, **kwargs):
        q = request.GET.get('q')
        error = ''
        if not q:
            error = "error message"
        return render(request, self.template_name, {'error': error})

comecando.html (template)

<form method="get">
  <input type="text" name="q">
  <input type="submit" value="Search">
</form> 

There are plenty of topics that are very similar to my problem but I've gone through lots of them and still couldn't solve it, here are a couple of examples that I've tried applying to my problem but didn't work out:

Gabriel Belini
  • 760
  • 1
  • 13
  • 32

2 Answers2

2

You had a good starting point and just need to finish the form handling correctly.

Change you parent view from TemplateView to FormView and adjust the necessary things: create a Form, add this to the view, adjust the template.

Then remove the get method and add this:

def form_valid(self, form):
    # store the user input here. These variables you can access then in your get_context_data method.
    self.q=form.cleaned_data['q']
    return super(ComecandoView, self).form_valid(form)

You need to change your template to: {{form.as_table}}

And replace the line where you grab the value to something meaningful: "q" has to be replaced by a field name of your form ("name" or "message").

ger.s.brett
  • 3,267
  • 2
  • 24
  • 30
  • thanks for your answer, I've tried what you said but still does not work, I've updated my topic explaining what happened, what I've tried and posted my code as it is now. – Gabriel Belini Jul 11 '17 at 12:04
  • I've just added the full traceback for the error I got. I've tried changing lots of things, first of all, I tried printing self.q inside the `form_valid` function, nothing happens. Also I tried printing the `self.q` inside the `get_context_data` function, but then I get the error ComecandoView has no attribute q. All of these printings were made after submitting a random text into the "comecando" html page input textfield – Gabriel Belini Jul 13 '17 at 11:41
1

I had a similar problem. I passed the input parameter into the url and reloaded the page

from django.shortcuts import reverse

def get_success_url(self):
    return reverse('<webpage>', kwargs={'q': self.request.POST.get('q')})

Then you can access it from kwargs in some method like get_context_data using for example kwargs['q']

In this case you would need to update your URL to hold the parameter 'q'. You can append '(?P<q>\d+)/$' to the url to achieve this

mattyx17
  • 806
  • 6
  • 11