Как передать значение URL из шаблона в метод form_valid внутри представления на основе классов в Django

Я начал работать с django и столкнулся с проблемой, которую не могу решить. Я считаю, что это должно быть просто, но я не могу разобраться.

Я получаю Id из шаблона, который я передаю через 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'),
]

Похоже, что это передает значение job_id в URL, поскольку после выбора флажка (в этом случае job_id указывает на 44) и нажатия на кнопку Run Next я попадаю на url, такой как:

http://localhost:8000/data/next/?job_id=44&Some-token

, что, на мой взгляд, хорошо. Теперь я хочу передать число 44 в представление, основанное на классе, что является проблемой, и я не смог этого сделать.

Как показано ниже, мне нужен job_id для запуска задачи run_next_task. Как мне получить этот 44 и передать его в метод form_valid внутри 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))

Я провел бесчисленные эксперименты.

job_id = self.request.GET.get('job_id') внутри form_valid и практически все остальные комбинации. Я пробовал использовать сессионные и глобальные переменные. Я пробовал использовать kwargs различными способами, например job_id=self.kwargs['job_id'].

Ни один из них не сработал. Должно быть что-то основное и фундаментальное, что я упускаю.

Любая помощь будет оценена по достоинству. Спасибо ;]

Я не пробовал это на себе, но просто попробуйте ;)

Я добавил новый атрибут в __init__
. Затем используйте его в 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...

Если вы хотите отправить данные с помощью формы, вы должны выбрать метод POST, а не GET. Добавьте "job_id" (или job.id. то, что вы передали) к значению input следующим образом:

  <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>

затем в представлении определите метод post:

class RunNextView(FormView):
     def post(self,request):
         # Since name='job_id'
         posted_id=request.POST["job_id"]
Вернуться на верх