You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django调用REST API时出现UnboundLocalError问题求助

UnboundLocalError when passing company_id to API call despite seeing correct value in debug

Problem Description

I'm trying to fetch a company_id from the result of cwObj.get_company(company), then pass that company_id to cwObj.get_sites(company_id) to retrieve site data. When I debug, I can see company_id has the expected value, but calling get_sites triggers an UnboundLocalError. I'm confused—does this mean the variable wasn't properly assigned? What's the best practice for assigning variables before making such API calls?

Relevant Code

views.py

def new_opportunity_location(request):
    company = request.GET.get('selected_company')
    company_obj = cwObj.get_company(company)
    company_id = company_obj[0]['id']
    sites = cwObj.get_sites(company_id)
    context = {'sites': sites}
    return render(request, 'website/new_opportunity_location.html', context)

API Client Methods

def get_company(self, request):
    try:
        r = requests.get(
            self.URL + 'company/companies?conditions=name="' + request + '"', headers=self.Header)
        r.raise_for_status()
    except:
        print(r.text)
        raise
    return r.json()

def get_sites(self, request):
    try:
        r = requests.get(
            self.URL + 'company/companies/' + request + '/sites', headers=self.Header)
        r.raise_for_status()
    except:
        print(r.text)
        raise
    return r.json()

Solution & Explanation

First, let's clear up your confusion: your company_id variable is almost certainly properly assigned (since you can see its value in debug). The UnboundLocalError is actually coming from a bug in your exception handling code, not from the company_id variable itself.

The Root Cause

Look at the except blocks in both get_company and get_sites:

except:
    print(r.text)
    raise

If the requests.get() call fails before assigning the response to r (e.g., a DNS failure, network timeout, or invalid URL construction), the r variable won't exist in the scope of the except block. When you try to print r.text, Python throws an UnboundLocalError because r hasn't been defined yet.

This makes it look like the error is related to passing company_id, but it's actually a separate issue with your error handling.

Fix the Exception Handling

Update your API client methods to avoid referencing r unless you know it's been assigned. Here's a better approach:

def get_company(self, company_name):
    # Rename parameter to avoid confusion with Django's request object
    url = f"{self.URL}company/companies?conditions=name=\"{company_name}\""
    try:
        r = requests.get(url, headers=self.Header)
        r.raise_for_status()
    except requests.exceptions.RequestException as e:
        # Handle all requests-related exceptions explicitly
        if 'r' in locals():
            print(f"API Error Response: {r.text}")
        print(f"Request Failed: {str(e)}")
        raise
    return r.json()

def get_sites(self, company_id):
    # Rename parameter for clarity, convert to string to avoid type issues
    company_id_str = str(company_id)
    url = f"{self.URL}company/companies/{company_id_str}/sites"
    try:
        r = requests.get(url, headers=self.Header)
        r.raise_for_status()
    except requests.exceptions.RequestException as e:
        if 'r' in locals():
            print(f"API Error Response: {r.text}")
        print(f"Request Failed: {str(e)}")
        raise
    return r.json()

Best Practices for Variable Assignment Before API Calls

  • Validate and sanitize inputs
    Check that company = request.GET.get('selected_company') is not None before passing it to get_company. Add a guard clause:
    company = request.GET.get('selected_company')
    if not company:
        # Handle missing company parameter (e.g., return 400 Bad Request)
        return HttpResponseBadRequest("Selected company is required")
    
  • Handle empty/non-existent API results
    company_obj = cwObj.get_company(company) could return an empty list if no matching company is found. Add a check:
    if not company_obj:
        return HttpResponseNotFound("Company not found")
    company_id = company_obj[0]['id']
    
  • Use type conversion explicitly
    If company_id is an integer, convert it to a string before concatenating into the URL (as shown in the fixed get_sites method) to avoid TypeError.
  • Avoid generic exception handlers
    Catching all exceptions with except: is bad practice—it can hide unexpected errors. Instead, catch specific exceptions like requests.exceptions.RequestException to handle API-related issues.
  • Rename parameters for clarity
    Using request as a parameter name in your API client methods is confusing because it clashes with Django's HttpRequest object. Use descriptive names like company_name or company_id instead.

内容的提问来源于stack exchange,提问作者garmars

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:27:41