UnboundLocalError: локальная переменная 'formset' ссылается перед присвоением в DJANGO

Эй, у меня есть список кампаний, у которых есть кнопка для запуска и остановки процесса.

'''

from django.shortcuts import render
from .models import Campaign
from .forms import CampaignForm, CampaignStatusFormSet

def home_view(request):
    queryset = Campaign.objects.all()

    if request.method == 'POST':
        form_type = request.POST.get('id')
        if form_type == 'campaign_status':
            formset = CampaignStatusFormSet(
                request.POST, request.FILES,
                queryset=queryset,
            )
            for form in formset.forms:
                if form.is_valid():
                    form.save()
    else:
        formset = CampaignStatusFormSet(queryset=queryset)

    campaigns_and_forms = list(zip(queryset, formset))

    context = {
        'formset': formset,
        'campaigns_and_forms': campaigns_and_forms,
    }

    return render(request, 'campaigns_in_progress.html', context)

'''

Но когда я запускаю его и нажимаю на кнопку, чтобы изменить воспроизведение/паузу, он показывает эту ошибку.

UnboundLocalError: локальная переменная 'formset' ссылается перед присвоением

Может ли кто-нибудь помочь мне рефакторить этот код так, чтобы он не показывал эту ошибку?

Вы можете убрать блок else, чтобы набор форм был доступен даже после нажатия на кнопки play/pause. Когда вы отправляете POST запрос, и campaign_status соответствует ожидаемому, переменная formset недоступна в conext и отсюда ошибка.

  from django.shortcuts import render
  from .models import Campaign
  from .forms import CampaignForm, CampaignStatusFormSet
  
  def home_view(request):
      queryset = Campaign.objects.all()
  
      if request.method == 'POST':
          form_type = request.POST.get('id')
          if form_type == 'campaign_status':
              formset = CampaignStatusFormSet(
                  request.POST, request.FILES,
                  queryset=queryset,
              )
              for form in formset.forms:
                  if form.is_valid():
                      form.save()
            # Set form with new created campaign         
            queryset = Campaign.objects.all()
            formset = CampaignStatusFormSet(queryset=queryset)

            campaigns_and_forms = list(zip(queryset, formset))

            context = {
                'formset': formset,
                'campaigns_and_forms': campaigns_and_forms,
            }

      else:
        formset = CampaignStatusFormSet(queryset=queryset)
        campaigns_and_forms = list(zip(queryset, formset))

        context = {
            'formset': formset,
            'campaigns_and_forms': campaigns_and_forms,
        }

    return render(request, 'campaigns_in_progress.html', context)

Для этого можно применить нехитрое решение. Создайте переменную formset с нулевым значением. Надеюсь, это решит вашу проблему.

Код:

from django.shortcuts import render
from .models import Campaign
from .forms import CampaignForm, CampaignStatusFormSet

def home_view(request):
    queryset = Campaign.objects.all()
    formset = ""
    if request.method == 'POST':
        form_type = request.POST.get('id')
        if form_type == 'campaign_status':
            formset = CampaignStatusFormSet(
                request.POST, request.FILES,
                queryset=queryset,
            )
            for form in formset.forms:
                if form.is_valid():
                    form.save()
    else:
        formset = CampaignStatusFormSet(queryset=queryset)

    campaigns_and_forms = list(zip(queryset, formset))

    context = {
        'formset': formset,
        'campaigns_and_forms': campaigns_and_forms,
    }

    return render(request, 'campaigns_in_progress.html', context)

Я не знаю, правильное ли это решение и не сломает ли оно что-то еще, но пока что все работает отлично. Я просто объявил набор форм перед оператором if, так что он как бы объявляется 2 раза.

Если кто-нибудь может сказать мне, является ли это хорошим решением, я буду очень благодарен

'''

def home_view(request):
    queryset = Campaign.objects.all()

    formset = CampaignStatusFormSet(
        request.POST, request.FILES,
        queryset=queryset,
    )

    if request.method == 'POST':
        form_type = request.POST.get('id')
        if form_type == 'campaign_status':
            formset = CampaignStatusFormSet(
                request.POST, request.FILES,
                queryset=queryset,
            )
            for form in formset.forms:
                if form.is_valid():
                    form.save()
    else:
        formset = CampaignStatusFormSet(queryset=queryset)

    campaigns_and_forms = list(zip(queryset, formset))

    context = {
        'formset': formset,
        'campaigns_and_forms': campaigns_and_forms,
    }

    return render(request, 'campaigns_in_progress.html', context)

'''

Вернуться на верх