Django

Code

ManipulatorScript: make_manipulator.py

File make_manipulator.py, 4.7 kB (added by Le Roux Bodenstein, 2 years ago)

made it work with post-magic-removal code, added some fixes and a project parameter

Line 
1 #!/usr/bin/env python
2
3 from optparse import OptionParser
4 import sys
5 import os
6
7 try:
8     import settings
9 except ImportError:
10     print "Settings file not found.  Place this file in the same place as manage.py"
11     sys.exit()
12
13 project_directory = os.path.dirname(settings.__file__)
14 project_name = os.path.basename(project_directory)
15 sys.path.append(os.path.join(project_directory, '..'))
16 project_module = __import__(project_name, '', '', [''])
17 sys.path.pop()
18 os.environ['DJANGO_SETTINGS_MODULE'] = '%s.settings' % project_name
19
20 from django.db import models
21 from django.template import Context, Template
22
23 p = OptionParser()
24
25 p.add_option("-p", "--project", dest="project", help="The project which contains the model")
26 p.add_option("-a", "--app", dest="app", help="The app which contains the model")
27 p.add_option("-m", "--model", dest="model", help="The model to produce the form for")
28 p.add_option("-n", "--name", dest="name", help="The name of the custom manipulator")
29
30 options, args = p.parse_args()
31
32 if not (options.model and options.app):
33     p.print_help()
34     sys.exit()
35
36 if not options.name:
37     options.name = "%s%s" % (options.app, options.model)
38
39 m = __import__("%s.%s.models" % (options.project, options.app), '', '', [options.model])
40
41 a = getattr(m, options.model)
42
43 def argValue(s, args):
44     if s == 'related_query_name':
45         return "???"
46     else:
47         return args[s]
48        
49 def field_text(field):
50     d = field.__dict__
51     args = dict([(f, isinstance(d[f], str) and "'%s'" % d[f] or d[f]) for f in d if f not in ['db_index', 'primary_key', 'rel', 'core', 'creation_counter',
52     'editable', 'name', 'default', 'column', 'attname', 'auto_now_add', 'help_text', 'auto_now', 'unique', 'verbose_name']])
53     if args['blank'] is True or args['null'] is True:
54         args['is_required'] = False
55     else:
56         args['is_required'] = True
57     try:
58         del(args['blank'])
59         del(args['null'])
60     except KeyError:
61         pass
62     try:
63         args['validator_list'] = ['%s' % v.__name__ for v in args['validator_list']]
64     except KeyError:
65         pass
66     if field.__class__.__name__ == 'CharField':
67         fieldType = 'TextField'
68     if field.__class__.__name__ == 'TextField':
69         fieldType = 'LargeTextField'
70     elif field.__class__.__name__ == 'ForeignKey':
71         fieldType = 'SelectField'
72         args['choices'] = "[('','-------')] + [(o.id, o) for o in %s.get_list()]" % (field.name.lower() + "s",)
73     elif field.__class__.__name__ == 'BooleanField':
74         fieldType = 'CheckboxField'
75     elif field.__class__.__name__ == 'DateTimeField':
76         fieldType = 'DatetimeField'
77     elif field.__class__.__name__ == 'ManyToManyField':
78         fieldType = 'SelectMultipleField'
79         args['choices'] = "[(o.id, o) for o in %s.get_list()]" % (field.name.lower() + "s",)
80     else:
81         fieldType = field.__class__.__name__
82    
83     extra_args = ["%s=%s" % (s, argValue(s, args)) for s in args if args[s] not in [None, '', False, []]]
84     #print field.name, extra_args
85     if extra_args:       
86         return '''\
87             forms.%s(field_name='%s', %s),''' % (fieldType, field.name, ', '.join(extra_args))
88     else:
89         return '''\
90             forms.%s(field_name='%s'),''' % (fieldType, field.name)
91
92 def value_text(field):
93     return """\
94                 %s=new_data['%s']""" % (field.name, field.name)
95
96 def m2m_text(field):
97     return """        temp.set_%s(newdata['%s'])""" % (field.name, field.name)
98
99 template = Template(
100 """class {{ name }}Manipulator(forms.Manipulator):
101     def __init__(self, pk=None):
102         if pk:
103             # change
104             self.original_object = {{model}}.objects.get(id=pk)
105             self.pk = pk
106         else:
107             # add
108             self.original_object = None
109             self.pk = None
110         
111         self.fields = (
112 {{ fields }}
113         )
114
115     def save(self, new_data):
116         if self.original_object:
117             # update
118             temp = dict(
119 {{ values }}           
120             )
121             for k,v in temp.iteritems():
122                 self.original_object.__setattr__(k, v)
123             self.original_object.save()           
124             return {{model}}.objects.get(id=pk)
125             
126         else:
127             # insert
128             temp = {{ model }}(
129 {{ values }}
130             )
131 {{ m2m }}
132             temp.save()
133             return temp
134         """)
135
136 context = Context({'fields': '\n'.join([field_text(f) for f in a._meta.fields + a._meta.many_to_many if f.name !='id']),
137                 'name': options.name,
138                 'model': options.model,
139                 'values': ',\n'.join([value_text(f) for f in a._meta.fields if f.name != 'id']),                               
140                 'm2m': '\n'.join([m2m_text(f) for f in a._meta.many_to_many])})
141 print template.render(context)