【发布时间】:2020-11-29 22:05:00
【问题描述】:
我收到 AttributeError 'NoneType' 对象没有属性 'model'
首先,让我解释一下我有两种形式。用户遇到的第一个表单是 InitialSearchForm。它需要一个日期输入、一个选定对象(旅行的实例)和一个整数(乘客人数)。 InitialSearchForm 中的 POST 请求数据被发送到 TripSelection 视图。此数据用于查询数据库并检索查询集,该查询集将用作我的第二种形式 - DateChoiceForm - 在 HttpResponse 中呈现的选择集。
以下代码用于 views.py 中的 TripSelection 视图。在初始化 DateChoiceForm 时,我将查询集作为参数“trips”传递:
class TripSelection(View):
""" A view to show results of search """
template = "bookings/trips_available.html"
def post(self, request):
"""
Takes the POST data from the InitialSearchForm and uses it to
initialise the DateChoiceForm before passing to the template
"""
form = InitialSearchForm(request.POST)
if form.is_valid():
destination_choice = request.POST.get("destination")
searched_date = request.POST.get("request_date")
passenger_total = int(request.POST.get("passengers"))
# Find trips with enough seats for requested no. of passengers
available_trips = Trip.objects.filter(
destination=destination_choice
).filter(seats_available__gte=passenger_total)
# Refine to trips with dates closest to searched_date
# limit to 3 results
gte_dates = available_trips.filter(
date__gte=searched_date
).order_by("date")[
:3
] # Returns trips that either match or are post- searched_date
lt_dates = available_trips.filter(date__lt=searched_date).order_by(
"-date"
)[
:3
] # Returns trips that are pre- searched_date
# Merge both queries
trips = gte_dates | lt_dates
naive_searched_date = datetime.strptime(searched_date, "%Y-%m-%d")
# Find trip closest to searched_date and make timezone naive
if gte_dates:
date_gte = gte_dates[0]
naive_closest_gte = self.timezone_naive(date_gte)
if lt_dates:
date_lt = lt_dates[0]
naive_closest_lt = self.timezone_naive(date_lt)
if (
naive_closest_gte - naive_searched_date
> naive_searched_date - naive_closest_lt
):
default_selected = date_lt
else:
default_selected = date_gte
else:
default_selected = date_gte
elif lt_dates:
date_lt = lt_dates[0]
naive_closest_lt = self.timezone_naive(date_lt)
default_selected = date_lt
else:
messages.error(
request,
"Sorry, there are no dates currently available for the"
"selected destination.",
)
form = DateChoiceForm(
trips=trips,
initial={
"trip_date": default_selected,
"num_passengers": passenger_total,
},
)
return render(request, self.template, {"form": form})
def timezone_naive(self, query_object):
""" Turns date attributes to a time-zone naive date """
date_attr = query_object.date
date_string = date_attr.strftime("%Y-%m-%d")
date_obj_naive = datetime.strptime(date_string, "%Y-%m-%d")
return date_obj_naive
在 forms.py 中,我在表单的 __init__ 方法中为字段“trip”设置了查询集:
class DateChoiceForm(forms.Form):
num_passengers = forms.IntegerField(widget=forms.HiddenInput())
trip = forms.ModelChoiceField(
queryset=None,
widget=forms.RadioSelect()
)
def __init__(self, *args, **kwargs):
trips = kwargs.pop('trips', None)
super(DateChoiceForm, self).__init__(*args, **kwargs)
self.fields['trip'].queryset = trips
表单在模板中按预期呈现,但是当我做出选择并单击表单上的“提交”时,我得到了 AttributeError。
这是在处理 DateChoiceForm 的 POST 数据的视图中引起的,特别是在 form = DateChoiceForm(request.POST) 行:
def trip_confirmation(request):
if request.method == "POST":
form = DateChoiceForm(request.POST)
if form.is_valid():
passengers = request.POST.get("num_passengers")
trip_choice = request.POST.get("trip")
print(trip_choice)
else:
print("Hello")
template = "bookings/confirm/trip.html"
context = {
"passengers": passengers,
"trip_choice": trip_choice
}
return render(request, template, context)
print("Error!").
如果我理解正确,这是因为从视图传递了查询集并在 __init__ 方法中设置了查询集,现在每次我调用 DateChoiceForm 时,它都希望发送一个参数来初始化表单。由于这次我没有传递任何参数,所以它到达这一行:trips = kwargs.pop('trips', None) 并采用 None 的后备值。
我不知道如何设置此表单字段的查询集,因为它不是我可以在 forms.py 中执行的简单静态过滤器。还有另一种方法吗?我目前唯一的解决方法是将第一个表单的发布请求数据传递到会话存储,在视图中检索它并创建相同的查询集作为参数传递给 DateChoiceForm(request.POST)
【问题讨论】:
-
分享完整视图。
-
我编辑以包含完整视图
-
为什么在
request.method == 'POST'的情况下使用InitialSearchForm? -
InitialSearchForm 用在另一个模板上——我只是设置了这个视图的动作来处理帖子数据
-
处理
DateChoiceForm的POST请求的视图是什么?看来你那边没有设置DateChoiceForm(request.POST, trips=...)。
标签: python django attributeerror