Django 2.1.2
我几乎成功地将一个复选框添加到了django管理员列表视图中,该列表未链接到基础模型中的字段。相反,我想根据复选框的值更新模型中的字段。
阅读了here个帖子后,它基本上可以正常工作。我的问题是,如果我在表单中覆盖save(),django会在其他地方中断,说“'NoneType'对象没有属性'save'”。
我有一个 TrainingSession (培训课程)模型,其中包含 submitted_date (提交日期)和 accepted_date (接受日期)。以下代码在列表视图中显示一个复选框,如果设置了acceptd_date,则默认为选中;如果未设置Submitted_date,则该复选框为禁用状态。我的计划是,如果选中此复选框,则将接受日期设置为今天:
class TrainingSessionListForm(forms.ModelForm):
accept = forms.BooleanField(required=False)
class Meta:
model = TrainingSession
fields = '__all__'
def __init__(self, *args, **kwargs):
instance = kwargs.get('instance')
if instance:
initiallyApproved = instance.accepted_date is not None
submittedForApproval = instance.submitted_date is not None
initial = kwargs.get('initial', {})
initial['accept'] = initiallyApproved
self.base_fields['accept'].disabled = not submittedForApproval
kwargs['initial'] = initial
super(TrainingSessionListForm, self).__init__(*args, **kwargs)
def save(self, *args, **kwargs):
instance = kwargs.get('instance')
if instance:
accepted = self.cleaned_data['accept']
if accepted and instance.accepted_date is None:
instance.accepted_date = datetime.date.today()
super(TrainingSessionListForm, self).save(*args, **kwargs)
class TrainingSessionAdmin(admin.ModelAdmin):
list_display = ['course','learner','submitted_date','accepted_date','accept']
list_editable = ['learner'] #needed so the editable form works
list_display_links = ['course']
def get_changelist_form(self, request, **kwargs):
return TrainingSessionListForm
def accept(self, obj=None):
#needed so list_display doesn't complain
pass
如果在更改值后单击“保存”,则会收到以下回溯:
Django Version: 2.1.2
Python Version: 3.6.7
Installed Applications:
['assessment.apps.AssessmentConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'crispy_forms']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
Traceback:
File "C:\Users\Aaron\AppData\Local\Programs\Python\Python36\lib\site-packages\django\core\handlers\exception.py" in inner
34. response = get_response(request)
File "C:\Users\Aaron\AppData\Local\Programs\Python\Python36\lib\site-packages\django\core\handlers\base.py" in _get_response
126. response = self.process_exception_by_middleware(e, request)
File "C:\Users\Aaron\AppData\Local\Programs\Python\Python36\lib\site-packages\django\core\handlers\base.py" in _get_response
124. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\Aaron\AppData\Local\Programs\Python\Python36\lib\site-packages\django\contrib\admin\options.py" in wrapper
604. return self.admin_site.admin_view(view)(*args, **kwargs)
File "C:\Users\Aaron\AppData\Local\Programs\Python\Python36\lib\site-packages\django\utils\decorators.py" in _wrapped_view
142. response = view_func(request, *args, **kwargs)
File "C:\Users\Aaron\AppData\Local\Programs\Python\Python36\lib\site-packages\django\views\decorators\cache.py" in _wrapped_view_func
44. response = view_func(request, *args, **kwargs)
File "C:\Users\Aaron\AppData\Local\Programs\Python\Python36\lib\site-packages\django\contrib\admin\sites.py" in inner
223. return view(request, *args, **kwargs)
File "C:\Users\Aaron\AppData\Local\Programs\Python\Python36\lib\site-packages\django\utils\decorators.py" in _wrapper
45. return bound_method(*args, **kwargs)
File "C:\Users\Aaron\AppData\Local\Programs\Python\Python36\lib\site-packages\django\utils\decorators.py" in _wrapped_view
142. response = view_func(request, *args, **kwargs)
File "C:\Users\Aaron\AppData\Local\Programs\Python\Python36\lib\site-packages\django\contrib\admin\options.py" in changelist_view
1745. self.save_model(request, obj, form, change=True)
File "C:\Users\Aaron\AppData\Local\Programs\Python\Python36\lib\site-packages\django\contrib\admin\options.py" in save_model
1091. obj.save()
Exception Type: AttributeError at /admin/assessment/trainingsession/
Exception Value: 'NoneType' object has no attribute 'save'
如果我尝试以下两种方法之一,都会得到相同的结果:
def save(self, *args, **kwargs):
super(TrainingSessionListForm, self).save(*args, **kwargs)
def save(self, *args, **kwargs):
pass
还要注意:在我的 __ init __ 中,我必须使用 self.base_fields ,因为 self.fields 不存在(我是是新手,所以也许这只是我缺乏理解)。也是 type(self).__ name __ 是 TrainingSessionForm ,而不是 TrainingSessionListForm ?