3

视图.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,
                           })

模型.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)

对于初始值,显示默认格式。但是,如果我将该值保存到数据库,则值正在保存,但未显示所选格式(表单实例)。

4

4 回答 4

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 语句中使用长视图和长代码......

于 2013-07-23T01:36:21.760 回答
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,
    })

如果还是不行,请在我指定的点继续调试。

于 2013-07-23T14:17:19.207 回答
0

我怀疑你得到了MultipleObjectsReturned或其他一些例外Settings.objects.get(user=user.id)

正如您在 User 上所拥有的,一个用户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':
    ...
于 2013-07-20T10:02:20.150 回答
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它,它将在您检查是否发生 POST 请求之前覆盖您传递的数据initial,从而使您每次{'date_format' ...}初始 dict 时都会松动。

注意:我将设置重命名为settings_instandsettings_init只是为了更容易向您解释(并从您的角度了解发生了什么)。当然重新排列代码,因为它最适合您的需求(又名:我不知道这是否会破坏您代码中的其他内容。)

于 2013-07-16T11:39:21.620 回答