Я действительно долго боролся с этим кодом, и я не могу понять, что с ним не так. Я пытался реализовать 2 модели формы в одном представлении здесь. Таким образом, ShoesForm отображается только тогда, когда пользователь хочет создать или отредактировать обувной продукт. (Я скрываю форму, используя JavaScript). Поля в модели обуви все blank=True
, поэтому field.cleaned_data
всегда подтверждается.
Однако всякий раз, когда я пытаюсь отредактировать существующий предмет, не относящийся к обуви, я получаю сообщение об ошибке UnboundLocalError: local variable 'pid' referenced before assignment
. Я знаю, это означает, что есть случай, когда pid не назначен, но я не вижу его. Какие-либо предложения?
views.py
def create_or_update_inventory(request, product_id=None):
"""Combined form view for BaseInventory and Shoes model
The two available forms in the context are:
1. product_form: linked to BaseInventory model
2. shoes_form: linked to Shoes model
If the form is submitted, it will first create the product for the BaseInventory model.
If any of the forms inside the shoes_form is filled, it will take the product and link
it to the inventory field in the Shoes model and then it will save the shoes_form.
This vies uses the inventory_list/product_detail.html as its template.
"""
context = {}
# if form is posted, this happens
# TODO: fix pid not found when editing non-shoe item
if request.method == 'POST':
try:
instance = get_object_or_404(Product, product_id=product_id)
instance2 = get_object_or_404(Shoes, inventory__product_id=product_id)
product_form = ProductForm(request.POST, instance=instance)
shoes_form = ShoesForm(request.POST, instance=instance2)
pid = instance.product_id
except:
product_form = ProductForm(request.POST)
shoes_form = ShoesForm(request.POST)
if product_form.is_valid() and shoes_form.is_valid():
product_form.save()
pid = product_form.instance.product_id
product = Product.objects.get(product_id=pid)
# if the shoes_form is filled, save to Shoes model, else ignore this
if shoes_form.cleaned_data['collection'] or \
shoes_form.cleaned_data['material'] or \
shoes_form.cleaned_data['ground_type']:
shoes_form.cleaned_data['inventory'] = product
shoes_form.instance.inventory = product
shoes_form.save()
# redirect to view all fields
return HttpResponseRedirect(reverse('inventory_list:product-detail', kwargs={'product_id': pid}))
else:
if product_id:
# if the user wants to update product, fill in with preexisting values
item = Product.objects.get(product_id=product_id)
pid = item.product_id
product_form = ProductForm(
initial={
'product_id': item.product_id,
'name': item.name,
'color_primary': item.color_primary,
'color_secondary': item.color_secondary,
'category': item.category,
'description': item.description,
'gender': item.gender,
'active': item.active,
}
)
if item.category == Product.SHOES:
shoes_form = ShoesForm(
initial={
'collection': item.shoes.collection,
'material': item.shoes.material,
'ground_type': item.shoes.ground_type,
}
)
else:
shoes_form = ShoesForm()
else:
# if the user wants to create product, create empty form
product_form = ProductForm()
shoes_form = ShoesForm()
# the list of contexts for the front end
context.update({
'product_form': product_form,
'shoes_form': shoes_form,
'colors': Color.objects.all(),
})
return render(request, 'inventory_list/product_detail.html', context)
РЕДАКТИРОВАТЬ: журнал ошибок
Traceback (most recent call last):
File "/usr/local/lib/python3.6/site-packages/django/contrib/staticfiles/handlers.py", line 66, in __call__
return self.application(environ, start_response)
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/wsgi.py", line 146, in __call__
response = self.get_response(request)
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py", line 81, in get_response
response = self._middleware_chain(request)
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 37, in inner
response = response_for_exception(request, exc)
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 87, in response_for_exception
response = handle_uncaught_exception(request, get_resolver(get_urlconf()), sys.exc_info())
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 122, in handle_uncaught_exception
return debug.technical_500_response(request, *exc_info)
File "/usr/local/lib/python3.6/site-packages/django_extensions/management/technical_response.py", line 37, in null_technical_500_response
six.reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python3.6/site-packages/six.py", line 692, in reraise
raise value.with_traceback(tb)
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 35, in inner
response = get_response(request)
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py", line 128, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py", line 126, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python3.6/contextlib.py", line 52, in inner
return func(*args, **kwds)
File "/app/inventory_list/views.py", line 133, in create_or_update_inventory
return HttpResponseRedirect(reverse('inventory_list:product-detail', kwargs={'product_id': pid}))
UnboundLocalError: local variable 'pid' referenced before assignment