Я хочу добавить методы доставки в django-oscar, но получаю ошибку UnboundLocalError, хотя сделал все на странице документа.
Request Method: GET
Request URL: http://127.0.0.1:8000/checkout/shipping-address/
Django Version: 2.1.7
Exception Type: UnboundLocalError
Exception Value:
local variable 'methods' referenced before assignment
репозиторий.py
from oscar.apps.shipping import repository
from . import methods
class Repository(repository.Repository):
def get_available_shipping_methods(self, basket, user=None, shipping_addr=None, request=None, **kwargs):
methods = (methods.Standard(),)
if shipping_addr and shipping_addr.country.code == 'GB':
# Express is only available in the UK
methods = (methods.Standard(), methods.Express())
return methods
методы.py
from oscar.apps.shipping import methods
from oscar.core import prices
from decimal import Decimal as D
class Standard(methods.Base):
code = 'standard'
name = 'Shipping (Standard)'
def calculate(self, basket):
return prices.Price(
currency=basket.currency,
excl_tax=D('5.00'), incl_tax=D('5.00'))
class Express(methods.Base):
code = 'express'
name = 'Shipping (Express)'
def calculate(self, basket):
return prices.Price(
currency=basket.currency,
excl_tax=D('4.00'), incl_tax=D('4.00'))
Вы повторно используете одну и ту же переменную methods
как глобальную и как локальную переменную внутри repository.Repository.get_available_shipping_methods
. Лучше использовать другое имя переменной для возвращаемой переменной или импортировать с помощью as
. Ошибка, которую вы видите, связана с тем, что импортированный модуль methods
переназначается как tuple
.
Я вижу, что это есть в документах, но, похоже, в них есть ошибка.
С UnboundLocalError
вы, по сути, рассматриваете проблему масштаба. Очень простой пример:
x = 10
def foo():
x += 1
print x
foo()
Когда foo
выполняется, x недоступен для foo
. Поэтому немного измените импорт, чтобы избежать этого;
from oscar.apps.shipping import repository
from . import methods as shipping_methods
class Repository(repository.Repository):
def get_available_shipping_methods(self, basket, user=None, shipping_addr=None, request=None, **kwargs):
methods = (shipping_methods.Standard(),)
if shipping_addr and shipping_addr.country.code == 'GB':
# Express is only available in the UK
methods = (shipping_methods.Standard(), shipping_methods.Express())
return methods
Это очень хорошее решение. Большое спасибо.
Пожалуйста, опубликуйте полную трассировку стека.