1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85 | # $Id: form_changed.py 602 2008-02-29 15:02:58Z tguettler $
# $HeadURL: svn+ssh://svnserver/svn/modwork/trunk/utils/form_changed.py $
# Python
import logging
import itertools
# Django
from django import newforms as forms
from django.db import models
def form_changed(form):
debug=False
assert form.is_valid()
def diff_value(value, initial, name):
# If this is an instance of a model, then compare with the primary key
cls=getattr(value, "__class__")
if issubclass(cls, models.Model):
if debug:
logging.info(u"form_changed using primary key as value: %s %s %s" % (
form, name, value))
value=getattr(value, value._meta.pk.name)
if (not value) and (not initial) and (value==False or value!=0):
# None and empty string are equal
if debug:
logging.info(u"form_changed no diff: (None) %r %s %s %s" % (
form, name, value, initial))
return False
if value and not initial:
if debug:
logging.info(u"form_changed diff: value + not %r %s %r %s %r" % (
form, name, value, type(value),
initial))
return True
if unicode(value)!=unicode(initial):
if debug:
logging.info(u"form_changed diff: %r %s %s %s %s" % (form, name, value, type(value),
initial))
return True
if debug:
logging.info(u"form_changed no diff: %r %s %s %s" % (form, name, value, initial))
return False
for name, field in form.fields.items():
initial = form.initial.get(name, field.initial)
if callable(initial):
initial = initial()
if initial is None:
if isinstance(field, forms.ChoiceField) and not isinstance(field, forms.MultipleChoiceField):
if field.choices:
initial=None
# field.choices can be QuerySetIterator
# get first entry without getting whole Query.
for initial_tuple in field.choices:
initial=initial_tuple[0]
break
value=form.cleaned_data.get(name)
if isinstance(value, (list, tuple)):
if initial==None:
if not value:
if debug:
logging.info(u"form_changed no diff: %r %s %s %s" % (form, name, value, initial))
continue
if debug:
logging.info(u"form_changed diff: %r %s %s %s" % (form, name, value, initial))
return True
assert isinstance(initial, (list, tuple)), 'initial ist not a list: %s %s value=%s' % (
field, initial, value)
if len(initial)!=len(value):
if debug:
logging.info(u"form_changed diff length of lists different: %r %s %s %s" % (
form, name, value, initial))
return True
for value_item, initial_item in itertools.izip(value, initial):
if diff_value(value_item, initial_item, name):
return True
else:
if diff_value(value, initial, name):
return True
return False
|
Comments