帮助理解Django视图

时间:2011-03-11 01:28:38

标签: django

我正在尝试按照https://github.com/alex/django-ajax-validation/blob/master/ajax_validation/views.py

上列出的代码进行操作

我已经能够理解它的一小部分。我添加了评论,说明我对正在发生的事情的理解。

我真的很感激我在旁边的评论中列出的一些问题的帮助,我不太关注。

def validate(request, *args, **kwargs):

    # I thing it is some sort of initializations but I cannot really understand what's happening
    form_class = kwargs.pop('form_class')
    defaults = {
        'data': request.POST
    }
    extra_args_func = kwargs.pop('callback', lambda request, *args, **kwargs: {})
    kwargs = extra_args_func(request, *args, **kwargs)
    defaults.update(kwargs)
    form = form_class(**defaults)

    if form.is_valid(): #straightforward, if there is no error then the form is valid
        data = {
            'valid': True,
        }
    else:
    # if we're dealing with a FormSet then walk over .forms to populate errors and formfields
        if isinstance(form, BaseFormSet):  #I cannot really understand what is BaseFromSet
            errors = {}
            formfields = {}
            for f in form.forms: # I am guessing that this is for when there are multiple form submitted for validation
                for field in f.fields.keys(): # I think he is looping over all fields and checking for error. what does add_prefix () return? and what is formfields[]?
                    formfields[f.add_prefix(field)] = f[field]
                for field, error in f.errors.iteritems():
                    errors[f.add_prefix(field)] = error
            if form.non_form_errors():
                errors['__all__'] = form.non_form_errors() # what is the '__all__'?
        else:
            errors = form.errors
            formfields = dict([(fieldname, form[fieldname]) for fieldname in form.fields.keys()])

    # if fields have been specified then restrict the error list
        if request.POST.getlist('fields'): # I am having a hard time understanding what this if statement does.
            fields = request.POST.getlist('fields') + ['__all__']
            errors = dict([(key, val) for key, val in errors.iteritems() if key in fields])

        final_errors = {} # here the author of this code totally lost me.
        for key, val in errors.iteritems():
            if '__all__' in key: 
                final_errors[key] = val
            elif not isinstance(formfields[key].field, forms.FileField):
                html_id = formfields[key].field.widget.attrs.get('id') or formfields[key].auto_id
                html_id = formfields[key].field.widget.id_for_label(html_id)
                final_errors[html_id] = val
        data = {
            'valid': False or not final_errors,
            'errors': final_errors,
        }

    json_serializer = LazyEncoder() # Why does the result have to be returned in json?
    return HttpResponse(json_serializer.encode(data), mimetype='application/json')

validate = require_POST(validate) # a decorator that requires a post to submit

LazyEncoder

class LazyEncoder(JSONEncoder):
    def default(self, obj):
        if isinstance(obj, Promise):
            return force_unicode(obj)
        return obj

2 个答案:

答案 0 :(得分:4)

form_class = kwargs.pop('form_class')

这只是拉动通过URL conf传递的关键字参数form_class

(r'^SOME/URL/$', 'ajax_validation.views.validate', 
      {'form_class': ContactForm}, # this keyword argument.
       'contact_form_validate') 

BaseFormSet只是完成幕后工作的formset类。如果您不知道,请搜索来源! grep -ri "baseformset" .这是一个非常宝贵的工具。

看看django.forms.formsets,了解formset_factory如何基于BaseFormSet生成新的“formset”类,因此是工厂部分!


  

我猜这是为了提交多个表单进行验证时

是的,这正是formset的用途(处理多种形式)


  

我认为他正在遍历所有字段并检查错误。 add_prefix()返回什么?什么是formfields []?

是的,这将循环通过字段名称。

add_prefix()用于为表单字段名称添加特定表单的前缀。由于formset会多次重复表单元素,因此每个字段都需要一个唯一的前缀,例如0-field11-field1等。

formfields只是一个空字典,定义在上面几行。


  

什么是'所有'?

__all__定义在django.forms.forms

的顶部
NON_FIELD_ERRORS = '__all__'

正是这些非字段特定错误(例如2个字段中的约束)存储在错误字典中而不是errors[fieldname]


  

我很难理解if语句的作用。

作者留言:

# if fields have been specified then restrict the error list   
if request.POST.getlist('fields'): 

它正在检查您是否在URLConf中指定了要验证的任何特定字段,这不是django而是ajax_validation

你可以看到他只根据指定的字段覆盖了他的错误字典,因此仅对那些字段传递验证。

 errors = dict([(key, val) for key, val in errors.iteritems() if key in fields])

  

这里代码的作者完全失去了我。

作者已将自定义错误和字段字典映射到具有前缀的特定字段名称(与通常的FormSet相反,每个表单都有自己的错误字典,不知道formset本身),他可能在AJAX响应中使用它验证所有字段。

通常情况下,您可以迭代一个formset并按表单顺序查看表单上的错误,但如果您需要通过ajax验证所有错误,则不是这样。

拉线html_id的线应该在大多数情况下都是直接的,但它就在那里,因为表单小部件可以根据小部件是否是一个无线电选择,在ID的末尾添加有趣的东西。

来自消息来源:

# RadioSelect is represented by multiple <input type="radio"> fields,
# each of which has a distinct ID. The IDs are made distinct by a "_X"
# suffix, where X is the zero-based index of the radio field. Thus,
# the label for a RadioSelect should reference the first one ('_0').

  

为什么必须在json中返回结果?

因为它是一个ajax请求,javascript很容易吃掉json。


  

2-你可以通过这些代码行......

extra_args_func = kwargs.pop('callback', lambda request, *args, **kwargs: {})

返回一个名为'callback'的关键字参数(如果传入,它应该是一个接受request的函数并返回一个字典),如果不是,则返回一个lambda函数返回一个空字典。

我不确定具体用途是什么用于额外的上下文。您可以使用它来运行任意代码片段,而无需修改或子类化ajax_validation ...

答案 1 :(得分:0)

它可能会帮助您运行此代码,并将调试器断点放在某个位置,以便您可以单步执行并检查变量和方法。您只需将此行放在要中断的位置即可完成此操作:

import pdb; pdb.set_trace()

您将被转储到控制台的调试器中。