views.py
@login_required
@user_passes_test(lambda u: u.is_superuser)
def date_format(request):
save_msg = ''
user = request.user
try:
settings = Settings.objects.get(user=user.id)
settingsForm = SettingsForm(instance=settings)
except:
settings = None
settingsForm = SettingsForm(initial={'date_format':0, 'time_format':0})
if request.method == 'POST':
settingsForm = SettingsForm(request.POST, instance=settings)
if settingsForm.is_valid():
settings = settingsForm.save(commit=False)
settings.user = user
settings.save()
save_msg = 'Date format has been updated.'
return render(request,'setting/date_format.html',
{
'about_menu': True,
'date_tab':True,
'SettingsForm':settingsForm,
'save_msg': save_msg,
})
models.py
class Settings(models.Model):
user = models.ForeignKey(User, null=True)
date_format = models.BooleanField('Date format', default=False)
time_format = models.BooleanField('Time format', default=False)
is_contactlist_active = models.BooleanField('Contacts', default=True)
对于初始值,显示默认格式。但是,如果我将该值保存到数据库,则值将保存,但不会显示所选格式(表单实例)。
答案 0 :(得分:1)
诚实地说你的代码很难遵循 - 并且很难测试。首先用空函数拆分它:
def date_format(request):
settings = _retrieve_user_settings() # see below
form = _prepare_settings_form(settings) # see below
if request.method == 'POST':
form = _prepare_settings_form(settings, request.POST)
if form.is_valid():
_save_settings(form) # see below
save_msg = 'Date format has been updated.'
return render(request,'setting/date_format.html',
{
...
}
)
def _retrieve_user_settings()
"""
get the logged-in user settings or None if the user is logged off or doesn't have any settings
"""
pass
def _prepare_settings_form(settingsInstance=None, data=None)
"""
prepare the form with the settings provided
use default values if the settings are empty (to pre-fill the form)
"""
pass
def _save_settings(form) # this one is even better out of the view
# throw exception if the form wasn't validated
# retrieve the user for the new settings
# save the settings (attached to the user)
pass
在开始实现这3个新的小函数的代码之前,编写单元测试,并确保以一个好的工作代码结束。如果您认为这太费劲,请查看此StackOverflow线程的大小,以及您正在进行的手动测试的数量;)
这只是一个例子,你可以用不同的方式拆分代码 - 但是你应该在try语句中避免长视图和长代码......
答案 1 :(得分:0)
我不知道“当前答案”是什么样的,因为它已被删除,但我可以尝试向你提出一些建议:
...
user = request.user
try:
settings_inst = Settings.objects.get(user=user.id)
settings_init = None
settingsForm = SettingsForm(instance=settings_inst)
except:
settings_init = {'date_format':0, 'time_format':0}
settings_inst = None
settingsForm = SettingsForm(initial=settings_init)
if request.method == 'POST':
## if settings_inst is None, you should fallback using the initial settings dict ##
if settings_inst:
settingsForm = SettingsForm(request.POST, instance=settings_inst)
else:
settingsForm = SettingsForm(request.POST, initial=settings_init)
if settingsForm.is_valid():
...
在您的情况下,如果您使用settings = None
,它会覆盖您使用initial
传递的数据,然后再检查POST请求是否发生,每次{'date_format' ...}
初始字典时都会松动
注意:我将设置重命名为settings_inst
和settings_init
只是为了让您更容易向您解释(并从您的角度查看正在发生的事情)。当然会重新排列代码,因为它最符合您的需求(也就是说:如果这可能会破坏您代码中的其他内容,我不会知道。)
答案 2 :(得分:0)
我怀疑您MultipleObjectsReturned
获得了Settings.objects.get(user=user.id)
或其他例外情况。
在用户ForeignKey
上,用户可以有多个Settings
您可以将视图更改为
@login_required
@user_passes_test(lambda u: u.is_superuser)
def date_format(request):
save_msg = ''
user = request.user
try:
#to update latest settings for an user
settings = Settings.objects.filter(user=user.id).latest('id')
settingsForm = SettingsForm(instance=settings)
except:
settings = None
settingsForm = SettingsForm(initial={'date_format':0, 'time_format':0})
if request.method == 'POST':
#your existing code
...
或者如果您只想为每个用户设置一个设置,请使用OneToOne
关系
class Settings(models.Model):
user = models.OneToOneField(User, null=True)
....
然后您可以直接将其视为request.user.settings
。并将视图更新为
@login_required
@user_passes_test(lambda u: u.is_superuser)
def date_format(request):
save_msg = ''
user = request.user
if request.user.settings:
settingsForm = SettingsForm(instance=request.user.settings)
else:
settings = None
settingsForm = SettingsForm(initial={'date_format':0, 'time_format':0})
if request.method == 'POST':
...
答案 3 :(得分:0)
我正在结合其他人的几个解决方案,请尝试:
@login_required
@user_passes_test(lambda u: u.is_superuser)
def date_format(request):
save_msg = ''
user = request.user
try:
settings_instance = Settings.objects.filter(user=user.id).latest('id')
settings_initial = None
settingsForm = SettingsForm(instance=settings_instance)
except Settings.DoesNotExist:
settings_instance = None
settings_initial = {'date_format':0, 'time_format':0}
settingsForm = SettingsForm(initial=settings_initial)
print settings_instance # DEBUG here
if request.method == 'POST':
if settings_instance:
settingsForm = SettingsForm(request.POST, instance=settings_instance)
else:
settingsForm = SettingsForm(request.POST, initial=settings_initial)
if settingsForm.is_valid():
settings = settingsForm.save(commit=False)
settings.user = user
settings.save()
save_msg = 'Date format has been updated.'
return render(request, 'setting/date_format.html', {
'about_menu': True,
'date_tab':True,
'SettingsForm':settingsForm,
'save_msg': save_msg,
})
如果不起作用,请继续在我指定的位置进行调试。