简体   繁体   English

如何在Django中将非ModelForm表单保存到数据库

[英]How to save a non ModelForm form to database in Django

I'm a newbie Django user, struggling with submitting form data to the database. 我是Django的新手,正在努力将表单数据提交到数据库。 So that I can generate dynamic forms I am using a non-ModelForm form to capture field data. 为了生成动态表单,我正在使用非ModelForm表单来捕获字段数据。

I'm commented out validation for now but I am trying to capture the POST data from the form to the database. 我目前已取消验证,但我试图将POST数据从表单捕获到数据库。 The latest 'draft' of my views.py code is as follows - most interested in format from form_to_save = Scenario(...) : 我的views.py代码的最新“草案”如下-最感兴趣的格式来自form_to_save = Scenario(...)

def scenario_add(request, mode_from_url):
    urlmap = {
        'aviation': 'Aviation',
        'maritime': 'Maritime',
        'international_rail': 'International Rail',
        'uk_transport_outside_london': 'UK Transport (Outside London)',
        'transport_in_london': 'Transport in London',
    }
    target_mode = urlmap[mode_from_url]
    m = Mode.objects.filter(mode=target_mode)
    tl = m[0].current_tl.threat_l
    scenario_form = ScenarioForm(request.POST or None, current_tl=tl, mode=target_mode)
    if request.method == 'POST':
        #if scenario_form.is_valid():
        form_to_save = Scenario(
            target = Target(descriptor = scenario_form.fields['target']),
            t_type = ThreatType(t_type = scenario_form.fields['t_type']),
            nra_reference = NraReference(nra_code = scenario_form.fields['nra_reference']),
            subt = scenario_form.fields['subt'],
            ship_t = ShipType(ship_t = scenario_form.fields['ship_t']),
            likelihood = scenario_form.fields['likelihood'],
            impact = scenario_form.fields['impact'],
            mitigation = scenario_form.fields['mitigation'],
            compliance_score = scenario_form.fields['compliance_score'],
            notes = scenario_form.fields['notes']
        )
        form_to_save.save()
        # This needs to be changed to a proper redirect or taken to
        # a scenario summary page (which doesn't yet exit.)
        return render(request, "ram/new_scenario_redirect.html", {
            'scenario_form': scenario_form,
            'mode': mode_from_url,
            'mode_proper': target_mode
        })
    else:
        # if there is no completed form then user is presented with a blank
        # form
        return render(request, 'ram/scenario_add.html', {
            'scenario_form': scenario_form,
            'current_tl': tl,
            'mode': mode_from_url,
            'mode_proper': target_mode
        })

Any advice gratefully received. 非常感谢收到任何建议。 Many thanks. 非常感谢。

You've commented out the is_valid check, for some reason. 由于某种原因,您已经注释掉了is_valid检查。 You need that: as well as checking for validity, it also populates the form's cleaned_data dictionary which is what you should be getting the data from to create your object. 您需要:除了检查有效性以外,它还填充表单的cleaned_data字典,这是您应从中获取数据以创建对象的对象。 (And don't call that object "form_to_save": it's a model instance, not a form). (并且不要将该对象称为“ form_to_save”:它是模型实例,而不是表单)。

if request.method == 'POST':
    if scenario_form.is_valid():
        scenario = Scenario(
            target = Target(descriptor=scenario_form.cleaned_data['target']),
            t_type = ThreatType(t_type = scenario_form.cleaned_data['t_type'])
            ...etc

Plus, you should move the final "return render" call out of the else block, so that it is caught when the form is not valid, to show any errors. 另外,你应该将最后的“回归渲染”调用其他块的出来,所以,当窗体是无效的,显示的任何错误被抓住了。

However, as petkostas says, you would almost certainly be better off using an actual ModelForm in the first place. 但是,正如petkostas所说,首先肯定可以使用实际的ModelForm更好。

You can add custom options by overriding the init function in your form. 您可以通过覆盖表单中的init函数来添加自定义选项。 For example: 例如:

class SomeForm(forms.Form):
    department = forms.ChoiceField(widget=forms.Select, required=True)

... ...

    def __init__(self, *args, **kwargs):
        super(SomeForm, self).__init__(*args, **kwargs)
        self.fields['department'].choices = Department.objects.all().order_by('department_name).values_list('pk', 'department_name')

You can also change the queryset in the init function: where Department is a foreign key for example 您还可以在init函数中更改queryset:例如,Department是外键

queryset = Department.objects.filter(your logic)
self.fields['department'].queryset = queryset

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM