Home > Software engineering >  UnboundLocalError: local variable 'formset' referenced before assignment in DJANGO
UnboundLocalError: local variable 'formset' referenced before assignment in DJANGO

Time:08-19

Hey so I have this list of campaigns that have a button to start and stop the process.

'''

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)

'''

But when I run it and click on the button to change play/pause it shows this error.

UnboundLocalError: local variable 'formset' referenced before assignment

Can anyone help me refactor this code so that it doesn't show this error?

CodePudding user response:

You can apply a hacky solution for this. Create a formset variable with a null value. Hope it will resolve your issue.

Code:

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)

CodePudding user response:

You can remove the else block so that the formset is available even after clicking on the play/pause buttons. When you send a POST request, and campaign_status is as expected, formset variable is not available in the conext and hence the error.

  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)

CodePudding user response:

I don't know if this is the right solution and if it won't break something else but for now it works perfectly. I just declared the formset before the if statement so it kind of declares 2 times.

If anyone could tell me if this is a good solution I would be greatful

'''

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)

'''

  • Related