Ankh2054
Ankh2054

Reputation: 1153

Django: Access context data in POST and GET

I am very new to Django and I cannot work out how to access context data within a POST request so I don't have to repeat myself.

I believe that POST runs before get_context_data, but again unsure of what exactly to do here.

The page displays some data using a default of 30 days. Then on the page there is a form to override that value, which is passed back to the POST method to then re-render the page.

Example of page.

enter image description here

views.py

class ProducerDetailView3(generic.DetailView):
    model = Producer
    template_name = 'producer_detail3.html'
    
    def get_queryset(self, **kwargs):
        #-date_check means to descending order based on that column
        return Producer.objects.filter(owner_name__exact=self.kwargs['pk'],metasnapshot_date=date(1980, 1, 1))

    # Update context with more information
    def get_context_data(self, **kwargs):
        # Call the base implementation first to get the context
        context = super().get_context_data(**kwargs)
        # Cannot update context here as you are accessing existing producer object context data.
        # Create any data and add it to the context
        how_many_days = self.kwargs['days'] # get DAYS from URL. KWARGS are passed in from the get request
        context['day_filter'] = reverse('results:producer_detail', args=[self.kwargs['pk'], '300'])
        context['results'] = Results.objects.all().filter(owner_name__exact=self.kwargs['pk']).order_by('-date_check')
        context['chains_json_count'] = Results.objects.filter(owner_name__exact=self.kwargs['pk'],chains_json=True,date_check__gte=datetime.now()-timedelta(days=how_many_days)).count()
        return context

    def post(self, request,  **kwargs):
        day_filter = int(request.POST.get('day_filter'))
        producer = Producer.objects.get(owner_name__exact=kwargs['pk'],metasnapshot_date=date(1980, 1, 1))
        # Using reverse we create a URL to set the day filter to 300 and create a link
        results = Results.objects.all().filter(owner_name__exact=kwargs['pk']).order_by('-date_check')
        chains_json_count = Results.objects.filter(owner_name__exact=kwargs['pk'],chains_json=True,date_check__gte=datetime.now()-timedelta(days=day_filter)).count()
        context = {
            'producer': producer,
            'results': results,
            'chains_json_count': chains_json_count,
            'day_filter_url': day_filter
        }
        return render(request, 'producer_detail3.html', context)

producer_detail3.html

<h1>{{ producer.owner_name }}</h1>
<div class="row">
    <div class="col-md-8">
        <img src="{{ producer.logo_svg }}" alt="" width="100%">
    </div>
    <div class="col-md-4">
        <h5>Producer:owner_name{{ producer.owner_name }}</h5>
        <h5>Producer.pk: {{ producer.pk }}</h5>
        <!--a href="{{ day_filter_url }}"
                   class="btn btn-primary">
                   Set day filter to 300
                </a>
        <h5>{{ producer.url }}</h5-->

        <form method="post">
            <p><label for="day_filter">Set day filter value</label>
            {% csrf_token %}
            <input type="text" name="day_filter" size="40" id="day_filter"/></p>
            <input type="submit"/>
        </form>

        <br>
        <h5>Results: {{ chains_json_count }}</h5>
        <table>
            <tr>
              <th>HTTP</th> 
              <th>Hyperion</th>
              <th>Date</th>
            </tr>
            {% for result in results %}
            <tr>
                <td>{{result.http_check}}</td> 
                <td>{{result.hyperion_v2}}</td> 
                <td>{{result.date_check}}</td> 
            </tr>
            {% endfor %}
          </table>

    </div>
</div>

UPDATE:

I tried accessing the context via the POST method using:

def post(self, request,  **kwargs):
context = self.get_context_data(**kwargs)

However I get the following error:

Request Method: POST
Request URL:    http://127.0.0.1:8000/producers/dapplica/30
Django Version: 3.2.12
Exception Type: AttributeError
Exception Value:    
'ProducerDetailView3' object has no attribute 'object'
Exception Location: /Users/user/project/django-larn/lib/python3.7/site-packages/django/views/generic/detail.py, line 94, in get_context_data

Upvotes: 2

Views: 2512

Answers (1)

Razenstein
Razenstein

Reputation: 3717

there is no "hidden" call to get_context_data - you need to populate the context by calling the method from your post() method after defining self.object like

def post (....):
  ....
  # define the singel object to display
  self.object = self.get_object()
  # define the context
  context = self.get_context_data(**kwargs)
  # render
  return self.render_to_response(context)

if necessary add additional items to context in post()

Upvotes: 2

Related Questions