Django ListView с локальной переменной ModelForm 'instance', на которую ссылаются перед присвоением
У меня проблема с использованием modelform в моем generic.ListView. Когда я размещаю форму, я получаю ошибку, показанную ниже. Это работало с form.Form, но когда я перешел на form.ModelForm, я получил эту ошибку.
**Есть ли способ создать объект с ModelForm в generic.ListView ? **
Ошибка;
local variable 'instance' referenced before assignment
forms.py
from django import forms
from . import models
class ActionCreateForm(forms.ModelForm):
class Meta:
model = models.Action
fields = ('client_owner', 'contact_owner', 'topic', 'action_type', 'quote_price', 'quote_currency', 'statement', 'result', 'opportunity_type', 'file')
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['client_owner'] = forms.ModelChoiceField(required=True, queryset=models.Client.objects.all(), label="", widget=forms.Select(attrs={'class': 'form-control'}))
self.fields['contact_owner'] = forms.ModelChoiceField(required=False, queryset=models.Contact.objects.none(), label="", widget=forms.SelectMultiple(attrs={'class': 'form-control'}))
self.fields['topic'] = forms.CharField(required=True, max_length=100, label="", widget=forms.TextInput(attrs={'class':'form-control', 'placeholder': 'Topic'}))
if 'client_owner' in self.data:
try:
alan1 = int(self.data.get('client_owner'))
self.fields['contact_owner'] = forms.ModelChoiceField(required=False, queryset=models.Contact.objects.filter(client_owner_id = alan1), label="", widget=forms.SelectMultiple(attrs={'class': 'form-control'}))
except (ValueError, TypeError):
pass
elif self.instance.pk and self.instance.client_owner:
self.fields['contact_owner'].queryset = self.instance.client_owner.contact_client.order_by('name')
views.py
from django.shortcuts import render, redirect, get_object_or_404
from django.views import generic
from . import forms
from . import models
class ActionListView(generic.ListView): # action-listview
model = models.Action
context_object_name = 'all_actions'
template_name = 'crm/action_list.html'
ordering = ['-created']
def post(self, request, *args, **kwargs):
if 'submit_action_create_form' in self.request.POST:
action_form = forms.ActionCreateForm(self.request.POST, self.request.FILES)
if action_form.is_valid():
print("*** request.POST: ", request.POST)
client_obj = action_form.cleaned_data['client_owner']
contact_obj = action_form.cleaned_data['contact_owner']
topic_obj = action_form.cleaned_data['topic']
instance = models.Action.objects.create(user_owner = self.request.user, client_owner = client_obj, topic = topic_obj)
instance.contact_owner.set(contact_obj)
instance.save()
return redirect('action-detailview', slug=instance.slug)
def get_context_data(self, **kwargs):
context = super(ActionListView, self).get_context_data(**kwargs)
context['action_create_form'] = forms.ActionCreateForm
return context
Переместите возврат в оператор if и определите новый возврат для неудачного результата следующим образом:
if action_form.is_valid():
# rest of your code
return redirect('action-detailview', slug=instance.slug)
else:
return redirect ('/')
Вы можете заменить ('/') именем url, к которому привязан вид ActionListView.