我正在尝试按照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
答案 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-field1
,1-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()
您将被转储到控制台的调试器中。