Как я могу рефакторить свой код, чтобы убрать - "локальная переменная 'data' ссылается до присвоения".
Мой код предназначен для возврата набора запросов на основе выбранных дат или месяцев, однако эти два варианта почти одинаковы, но работает только один.
Вот мои обе формы.py
class DateInput(forms.DateInput):
input_type = 'date'
class MonthInput(forms.DateTimeInput):
input_type = 'month'
class DateRangeInputForm(forms.Form):
start = forms.DateField(widget=DateInput())
end = forms.DateField(widget=DateInput())
class MonthRangeInputForm(forms.Form):
start = forms.DateField(widget=MonthInput())
end = forms.DateField(widget=MonthInput())
Вот представление запроса, которое работает.
def milk_records_range_per_day(self, request):
if request.method == "POST":
form = forms.DateRangeInputForm(request.POST)
if form.is_valid():
data = (models.Milk.objects.filter(milking_date__date__range=(
form.cleaned_data['start'], form.cleaned_data['end']))
.annotate(date=functions.TruncDate("milking_date"))
.values("date")
.annotate(amt=Sum('amount_in_kgs')))
labels = [c['date'].strftime("%d-%m-%Y") for c in data]
values = [x['amt'] for x in data]
.......
Хотя здесь возникает ошибка ссылки: локальная переменная 'data' ссылается перед присвоением
def milk_records_range_per_month(self, request):
if request.method == "POST":
form = forms.MonthRangeInputForm(request.POST)
if form.is_valid():
data = (models.Milk.objects.filter(milking_date__month__range=(
form.cleaned_data['start'],form.cleaned_data['end']))
.annotate(month=functions.TruncMonth("milking_date"))
.values("month")
.annotate(amt=Sum('amount_in_kgs')))
labels = [c['month'].strftime("%m-%Y") for c in data]
values = [x['amt'] for x in data]
.....
Модель:
class Milk(models.Model):
amount_in_kgs = models.PositiveIntegerField(validators=[MinValueValidator(0), MaxValueValidator(50)])
milking_date = models.DateTimeField(auto_now_add=True)
...
Это происходит, когда ваша форма недействительна.
Вложение переменных, которые используют переменную data
помогло бы:
def milk_records_range_per_month(self, request):
if request.method == "POST":
form = forms.MonthRangeInputForm(request.POST)
if form.is_valid():
data = (models.Milk.objects.filter(milking_date__month__range=(
form.cleaned_data['start'],form.cleaned_data['end']))
.annotate(month=functions.TruncMonth("milking_date"))
.values("month")
.annotate(amt=Sum('amount_in_kgs')))
# Now the following two declarations are in this code block
# where "data" variable is declared already.
labels = [c['month'].strftime("%m-%Y") for c in data]
values = [x['amt'] for x in data]
.....
Вы также можете установить значение по умолчанию для переменной data
перед блоком кода if
:
data = []
if form.is_valid():
...
Решение зависит от вашего случая использования.
PS. проблема одинакова в обоих представлениях (milk_records_range_per_month
и milk_records_range_per_day
).