在我的表单中,我必须过滤“承租人”选择字段,以便它仅显示与活动用户的组织相关联的承租人。因此,我只是将一个额外的参数传递给表单构造函数。当我加载(GET)表单时,这可以按预期工作。
但是当我提交(POST)表单时,我不断收到以下错误:
AttributeError: 'NoneType' object has no attribute 'organization_profile'
你知道是什么在激怒这吗?
Views.py
def create_booking(request):
if request.method == "POST":
form = BookingCreateForm(data=request.POST)
if form.is_valid():
data = form.cleaned_data
booking = Booking.objects.create(
status=data['status'],
tenant = data['tenant'],
apartment = data['apartment'],
check_in = data['check_in'],
check_out = data['check_out'],
rent = data['rent'],
)
booking.save()
return redirect('dashboard:dashboard')
else:
form = BookingCreateForm(user=request.user)
return render(request, 'accounts/booking_form.html', {'form': form})
Forms.py
class BookingCreateForm(forms.ModelForm):
class Meta():
model = Booking
fields = '__all__'
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user',None)
super(BookingCreateForm, self).__init__(*args, **kwargs)
organization = self.user.organization_profile
self.fields['tenant'] = forms.ChoiceField(choices=[
(tenant.id, tenant.name)) for tenant in TenantProfile.objects.filter(organization=organization)
])
型号
class Booking(models.Model):
STATUS_OPTIONS = [
(0, 'Pending'),
(1, 'Accepted'),
(2, 'In-tenancy'),
(3, 'Moved-out'),
(4, 'Cancelled'),
]
status = models.PositiveSmallIntegerField(choices=STATUS_OPTIONS, default=0)
tenant = models.ForeignKey('TenantProfile', on_delete=models.CASCADE)
apartment = models.ForeignKey('Apartment', on_delete=models.CASCADE)
check_in = models.DateField(blank=False)
check_out = models.DateField(blank=False)
rent = models.DecimalField(max_digits=6, decimal_places=2, blank=False)
无论是GET请求还是POST请求,都需要传递用户,因此:
def create_booking(request):
if request.method == 'POST':
form = BookingCreateForm(data=request.POST, user=self.request.user)
# …
除非tenant
你Booking
的a是多少,否则CharField
这将无法工作,你需要使用ModelChoiceField
[Django-doc]。例如:
class BookingCreateForm(forms.ModelForm):
class Meta:
model = Booking
fields = '__all__'
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user',None)
super().__init__(*args, **kwargs)
organization = self.user.organization_profile
self.fields['tenant'].queryset = TenantProfile.objects.filter(
organization=organization
)
注意:你可以使用
@login_required
装饰器[Django-doc]将视图限制为仅通过身份验证的用户使用 。
绝对地; 我忘了在POST的表单构造函数中传递request.user。另外,对于第二种情况,您是正确的。“租户”字段是一个前键字段,因此我应该使用self.fields ['tenant'] = form.ModelChoiceField(queryset = TenantProfile.objects.filter(organization = organization))代替。我已经更新了我的问题,以包含我的Models.py来使其更清楚。如果您想在答案中包含forms.ModelChoiceField,以使人们获得完整的解决方案。谢谢!