1 | from django.forms.models import modelform_factory |
||
2 | from django.views.generic import ( |
||
3 | DetailView, |
||
4 | CreateView, |
||
5 | UpdateView, |
||
6 | DeleteView, |
||
7 | TemplateView |
||
8 | ) |
||
9 | from django_tables2 import SingleTableView |
||
10 | |||
11 | from crudbuilder.registry import registry |
||
12 | from crudbuilder.mixins import ( |
||
13 | CrudBuilderMixin, |
||
14 | BaseListViewMixin, |
||
15 | CreateUpdateViewMixin, |
||
16 | InlineFormsetViewMixin, |
||
17 | BaseDetailViewMixin, |
||
18 | LoginRequiredMixin |
||
19 | ) |
||
20 | from crudbuilder.abstract import BaseBuilder |
||
21 | from crudbuilder.tables import TableBuilder |
||
22 | from crudbuilder.helpers import ( |
||
23 | model_class_form, |
||
24 | plural, |
||
25 | reverse_lazy |
||
26 | ) |
||
27 | |||
28 | |||
29 | class ViewBuilder(BaseBuilder): |
||
30 | """View builder which returns all the CRUD class based views""" |
||
31 | |||
32 | def __init__(self, *args, **kwargs): |
||
33 | super(ViewBuilder, self).__init__(*args, **kwargs) |
||
34 | self.classes = {} |
||
35 | |||
36 | def generate_crud(self): |
||
37 | self.generate_list_view() |
||
38 | self.generate_create_view() |
||
39 | self.generate_detail_view() |
||
40 | self.generate_update_view() |
||
41 | self.generate_delete_view() |
||
42 | |||
43 | def get_actual_form(self, view): |
||
44 | if self.createupdate_forms and self.createupdate_forms.get(view, None): |
||
45 | return self.createupdate_forms.get(view) |
||
46 | elif self.custom_modelform: |
||
47 | return self.custom_modelform |
||
48 | else: |
||
49 | return self.generate_modelform() |
||
50 | |||
51 | def get_actual_table(self): |
||
52 | if self.custom_table2: |
||
53 | return self.custom_table2 |
||
54 | else: |
||
55 | table_builder = TableBuilder(self.app, self.model, self.crud) |
||
56 | return table_builder.generate_table() |
||
57 | |||
58 | def generate_modelform(self): |
||
59 | """Generate modelform from Django modelform_factory""" |
||
60 | |||
61 | model_class = self.get_model_class |
||
62 | excludes = self.modelform_excludes if self.modelform_excludes else [] |
||
63 | _ObjectForm = modelform_factory(model_class, exclude=excludes) |
||
64 | return _ObjectForm |
||
65 | |||
66 | def get_template(self, tname): |
||
67 | """ |
||
68 | - Get custom template from CRUD class, if it is defined in it |
||
69 | - No custom template in CRUD class, then use the default template |
||
70 | """ |
||
71 | |||
72 | if self.custom_templates and self.custom_templates.get(tname, None): |
||
73 | return self.custom_templates.get(tname) |
||
74 | elif self.inlineformset: |
||
75 | return 'crudbuilder/inline/{}.html'.format(tname) |
||
76 | else: |
||
77 | return 'crudbuilder/instance/{}.html'.format(tname) |
||
78 | |||
79 | def get_createupdate_mixin(self): |
||
80 | if self.inlineformset: |
||
81 | return InlineFormsetViewMixin |
||
82 | else: |
||
83 | return CreateUpdateViewMixin |
||
84 | |||
85 | def generate_list_view(self): |
||
86 | """Generate class based view for ListView""" |
||
87 | |||
88 | name = model_class_form(self.model + 'ListView') |
||
89 | list_args = dict( |
||
90 | model=self.get_model_class, |
||
91 | context_object_name=plural(self.model), |
||
92 | template_name=self.get_template('list'), |
||
93 | table_class=self.get_actual_table(), |
||
94 | context_table_name='table_objects', |
||
95 | crud=self.crud, |
||
96 | permissions=self.view_permission('list'), |
||
97 | permission_required=self.check_permission_required, |
||
98 | login_required=self.check_login_required, |
||
99 | table_pagination={'per_page': self.tables2_pagination or 10}, |
||
100 | custom_queryset=self.custom_queryset, |
||
101 | custom_context=self.custom_context, |
||
102 | custom_postfix_url=self.custom_postfix_url |
||
103 | ) |
||
104 | |||
105 | list_class = type( |
||
106 | name, |
||
107 | (BaseListViewMixin, SingleTableView), |
||
108 | list_args |
||
109 | ) |
||
110 | self.classes[name] = list_class |
||
111 | return list_class |
||
112 | |||
113 | View Code Duplication | def generate_create_view(self): |
|
0 ignored issues
–
show
Duplication
introduced
by
![]() |
|||
114 | """Generate class based view for CreateView""" |
||
115 | |||
116 | name = model_class_form(self.model + 'CreateView') |
||
117 | create_args = dict( |
||
118 | form_class=self.get_actual_form('create'), |
||
119 | model=self.get_model_class, |
||
120 | template_name=self.get_template('create'), |
||
121 | permissions=self.view_permission('create'), |
||
122 | permission_required=self.check_permission_required, |
||
123 | login_required=self.check_login_required, |
||
124 | inlineformset=self.inlineformset, |
||
125 | success_url=reverse_lazy('{}-{}-list'.format(self.app, self.custom_postfix_url)), |
||
126 | custom_form=self.createupdate_forms or self.custom_modelform, |
||
127 | custom_postfix_url=self.custom_postfix_url |
||
128 | ) |
||
129 | |||
130 | parent_classes = [self.get_createupdate_mixin(), CreateView] |
||
131 | if self.custom_create_view_mixin: |
||
132 | parent_classes.insert(0, self.custom_create_view_mixin) |
||
133 | |||
134 | create_class = type( |
||
135 | name, |
||
136 | tuple(parent_classes), |
||
137 | create_args |
||
138 | ) |
||
139 | |||
140 | self.classes[name] = create_class |
||
141 | return create_class |
||
142 | |||
143 | def generate_detail_view(self): |
||
144 | """Generate class based view for DetailView""" |
||
145 | |||
146 | name = model_class_form(self.model + 'DetailView') |
||
147 | detail_args = dict( |
||
148 | detailview_excludes=self.detailview_excludes, |
||
149 | model=self.get_model_class, |
||
150 | template_name=self.get_template('detail'), |
||
151 | login_required=self.check_login_required, |
||
152 | permissions=self.view_permission('detail'), |
||
153 | inlineformset=self.inlineformset, |
||
154 | permission_required=self.check_permission_required, |
||
155 | custom_postfix_url=self.custom_postfix_url |
||
156 | ) |
||
157 | |||
158 | detail_class = type(name, (BaseDetailViewMixin, DetailView), detail_args) |
||
159 | self.classes[name] = detail_class |
||
160 | return detail_class |
||
161 | |||
162 | View Code Duplication | def generate_update_view(self): |
|
0 ignored issues
–
show
|
|||
163 | """Generate class based view for UpdateView""" |
||
164 | |||
165 | name = model_class_form(self.model + 'UpdateView') |
||
166 | update_args = dict( |
||
167 | form_class=self.get_actual_form('update'), |
||
168 | model=self.get_model_class, |
||
169 | template_name=self.get_template('update'), |
||
170 | permissions=self.view_permission('update'), |
||
171 | permission_required=self.check_permission_required, |
||
172 | login_required=self.check_login_required, |
||
173 | inlineformset=self.inlineformset, |
||
174 | custom_form=self.createupdate_forms or self.custom_modelform, |
||
175 | success_url=reverse_lazy('{}-{}-list'.format(self.app, self.custom_postfix_url)), |
||
176 | custom_postfix_url=self.custom_postfix_url |
||
177 | ) |
||
178 | |||
179 | parent_classes = [self.get_createupdate_mixin(), UpdateView] |
||
180 | if self.custom_update_view_mixin: |
||
181 | parent_classes.insert(0, self.custom_update_view_mixin) |
||
182 | |||
183 | update_class = type( |
||
184 | name, |
||
185 | tuple(parent_classes), |
||
186 | update_args |
||
187 | ) |
||
188 | self.classes[name] = update_class |
||
189 | return update_class |
||
190 | |||
191 | def generate_delete_view(self): |
||
192 | """Generate class based view for DeleteView""" |
||
193 | |||
194 | name = model_class_form(self.model + 'DeleteView') |
||
195 | delete_args = dict( |
||
196 | model=self.get_model_class, |
||
197 | template_name=self.get_template('delete'), |
||
198 | permissions=self.view_permission('delete'), |
||
199 | permission_required=self.check_permission_required, |
||
200 | login_required=self.check_login_required, |
||
201 | success_url=reverse_lazy('{}-{}-list'.format(self.app, self.custom_postfix_url)), |
||
202 | custom_postfix_url=self.custom_postfix_url |
||
203 | ) |
||
204 | |||
205 | delete_class = type(name, (CrudBuilderMixin, DeleteView), delete_args) |
||
206 | self.classes[name] = delete_class |
||
207 | return delete_class |
||
208 | |||
209 | |||
210 | class CrudListView(LoginRequiredMixin, TemplateView): |
||
211 | template_name = "crudbuilder/cruds.html" |
||
212 | title = "Registered Cruds" |
||
213 | login_required = False |
||
214 | |||
215 | def cruds(self): |
||
216 | return registry.items() |
||
217 | |||
218 | |||
219 | crudlist_view = CrudListView.as_view() |
||
220 |