I started working with django and I have come across a problem that I am not able to solve. I believe this should be easy but I cannot figure it out.
I am getting an Id from a template which I pass through a URL.
data.html
...
<div class="container">
<form method="GET" action="{% url 'data:next' %}">
<input type="hidden" required name='job_id'>
<button type="submit" class="btn btn-primary">Run Next</button>
{% csrf_token %}
</form>
</div>
...
url.py
app_name = "data"
urlpatterns = [
...
...
path('next/', RunNextView.as_view(), name='next'),
]
This seems to pass the job_id value to the URL as after selecting a checkbox (in this case with job_id pointing at 44) and clicking on the Run Next button I get to a url such as:
http://localhost:8000/data/next/?job_id=44&Some-token
which I think is good. Now I want to pass the number 44 to a class based view which is the problem and I was not able to do it.
As shown below I need the job_id in order to run the run_next_task task. How do i grab that 44 and pass it to the form_valid method inside the CBV ?
views.py
class RunNextView(FormView):
template_name = 'next.html'
form_class = RunForm
success_url = reverse_lazy('data:list')
def dispatch(self, request, *args, **kwargs):
if not request.user.is_authenticated:
return redirect(reverse_lazy('account:login'))
else:
return super(RunNextView, self).dispatch(request, *args, **kwargs)
def form_valid(self, form):
cal = form.save(False)
cal.user = self.request.user
cal.save()
cal.send_update()
job_id = self.request.GET.get('job_id') //this way doesn't work
run_next_task.delay(pk=cal.pk, dir=job_id)
return redirect(self.success_url)
def form_invalid(self, form):
for field in form.errors:
form[field].field.widget.attrs['class'] = F" {form.error_css_class}"
return self.render_to_response(self.get_context_data(form=form))
I did countless experiments.
job_id = self.request.GET.get('job_id') inside the form_valid and pretty much every other combination. I tried using session and global variables. I tried using kwargs in many different ways such as job_id=self.kwargs['job_id'].
Non of them worked. There must be something basic and fundamental that I am missing.
Any help is appreciated. Thank you ;]
CodePudding user response:
I haven't tried this on my own but just give it a try ;)
I added a new attribute in __init__
Then use it in form_valid
.
class RunNextView(FormView):
template_name = 'next.html'
form_class = RunForm
success_url = reverse_lazy('data:list')
# Add this ↓
def __init__(self, **kwargs):
self.job_id = ""
super().__init__(self, **kwargs)
# Add this as well ↓
def get(self, request, *args, **kwargs):
self.job_id = request.GET.get('job_id')
super().get(self, request, *args, **kwargs)
# some code...
def form_valid(self, form):
# some code...
job_id = self.job_id # <- Change here
# some code...
# some code...
CodePudding user response:
If you want to send data with a form, you have to choose POST method not GET. add the "job_id" (or job.id. what ever u passed) to the value of the input as follow:
<form method="POST" action="{% url 'data:next' %}">
<input type="hidden" value="{{job_id}}" required name='job_id'>
<button type="submit" class="btn btn-primary">Run Next</button>
{% csrf_token %}
</form>
then in view, define a post method:
class RunNextView(FormView):
def post(self,request):
# Since name='job_id'
posted_id=request.POST["job_id"]