【问题标题】:Django ModelForm Submit To DatabaseDjango ModelForm 提交到数据库
【发布时间】:2013-07-27 01:39:11
【问题描述】:

当我在 localhost:8000/Scan 加载视图时,会引发以下问题:

TypeError on views.py in Scan, line 27:

form = Scan() # Otherwise, set the form to unbound

知道我在这里做错了什么吗?我试图研究,但找不到答案。 (这里是 Django 新手)。谢谢大家!

Views.py

from django.http import HttpResponse
from Scanner.forms import SubmitDomain

def Scan(request):
    if request.method == 'POST': # If the form has been submitted...
        form = SubmitDomain(request.POST) # A form bound to the POST data
    if form.is_valid(): # If form input passes initial validation...
        form.cleaned_data['domainNm']  ## clean data in dictionary
        try:
            ## check if Tld Table has submitted domain already
            from Scanner.models import Tld
            Tld.objects.get(domainNm=form.cleaned_data['domainNm'])

        except Tld.DoesNotExist:
            print "Would you like to create an account?"
            ## redirect to account creation

        else:
            print "Do you have an account? Please login."
            ## redirect to account login

    else:
        form = Scan() # Otherwise, set the form to unbound

Forms.py

from django.forms import ModelForm
from Scanner.models import Tld

class SubmitDomain(ModelForm):

    class Meta:
        model = Tld #Create form based off Model for Tld
        fields = ['domainNm',]

    def clean_domainName(self):
        val = self.clean_domainName('domainNm')
        return val

## This creates the form.
form = SubmitDomain()

【问题讨论】:

    标签: python django views django-forms


    【解决方案1】:

    在您的模型表单中:

    from django.forms import ModelForm
    from Scanner.models import Tld
    
    class SubmitDomainForm(ModelForm):
        class Meta:
            model = Tld
            fields = ['domainNm']
    
        def clean_domainName(self):
            val = self.cleaned_data.get('domainNm')
            if Tld.objects.filter(domainNm=val).count() > 0:
                raise forms.ValidationError(u'Sorry that domain already
                    exists, etc, etc')
            return val
    

    在你看来,这样做:

    from django.shortcuts import render
    from Scanner.forms import SubmitDomainForm
    
    def scan(request):  # functions should start with a lowercase letter
        # Bind the post data to the form, if it exists.
        # No need for a separate if statement here
        form = SubmitDomainForm(request.POST or None)
    
        if request.method == 'POST':
            if form.is_valid():
                # save your model form, or do something else
    
        return render(request, 'your-template.html', {'form': form})
    

    希望对您有所帮助。您的视图当前正在为表单实例化错误类型的对象,因此出现 TypeError。您当前在模型表单上的 clean 方法将永远不会验证任何内容。它只是将值设置为等于 clean 函数。不要让表单验证逻辑使您的视图混乱,而是将其放入该字段的表单的 clean 方法中,您可以针对不同的条件引发异常。

    【讨论】:

    • 那么,try{} 和 except{} 块应该放在表单本身中吗?
    • 是的。视图不是您想要放置表单验证逻辑的地方:)
    • 哈哈,好吧,正如我所说,我仍然非常需要整个 MTV 的东西,但我确实学到了很多东西。那么,这是否被认为是服务器端验证,因为它是在模型验证之外进行验证的?作为最佳实践,是否需要额外验证?
    • 我总是在服务器上进行验证。如果我通过 ajax 提交表单,我仍然会从视图中以 JSON 形式返回验证错误,而不是使用完全独立的代码库进行客户端验证。这只会使您的维护工作加倍。无论如何,您都必须进行服务器端验证,因为 JavaScript 可以关闭。
    • 不客气。 Django 是一个很棒的框架,在表单方面特别强大。如果您还没有,您可以通过djangobook.com 上的教程进行操作。 “Practical Django Projects”一书对我的起步也有很大帮助。
    【解决方案2】:

    reuqest.method != "POST" 时失败,这种情况下没有定义表单

    【讨论】:

      【解决方案3】:

      问题不是特定于 django,它是基本的 python。你的缩进是错误的。代码应该是这样的:

      if request.method == 'POST':
          form = SubmitDomain(request.POST)
          if form.is_valid(): # indent fixed here
              form.cleaned_data['domainNm'] 
      

      【讨论】:

      • 天哪,哇。我得习惯这个缩进的东西:)。非常感谢!
      • 问题是,我做了这个,然后又出现了另一个类型错误。请查看更新后的问题
      • 此外,读取 form.cleaned_data['domainNm'] 的代码行并没有按照您的想法执行。具体来说,它不会清除表单的“domainNm”数据。它只是访问清理后的值(假设已在表单上调用了 clean()),然后您将丢弃该值。
      • @CodeTalk 我不确定“将表单设置为未绑定”是什么意思,但通常当表单无效时,您只需重新呈现网页并显示表单验证错误给用户。见docs.djangoproject.com/en/dev/topics/forms
      猜你喜欢
      • 2019-02-08
      • 2018-07-07
      • 2018-10-10
      • 1970-01-01
      • 2013-08-19
      • 1970-01-01
      • 1970-01-01
      • 2012-06-05
      相关资源
      最近更新 更多