表单实例未显示

时间:2013-07-09 14:46:32

标签: django django-models django-forms django-templates django-views

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)

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

4 个答案:

答案 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_instsettings_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,
    })

如果不起作用,请继续在我指定的位置进行调试。