Reputation: 1153
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.
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
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