Ticket #4236: create_update_newforms.diff
File create_update_newforms.diff, 13.9 KB (added by , 18 years ago) |
---|
-
django/views/generic/create_update.py
1 from django import newforms as forms 2 from django.contrib.auth.views import redirect_to_login 3 from django.core.exceptions import ObjectDoesNotExist, ImproperlyConfigured 1 4 from django.core.xheaders import populate_xheaders 2 from django.template import loader3 from django import oldforms4 5 from django.db.models import FileField 5 from django.contrib.auth.views import redirect_to_login6 from django.template import RequestContext7 6 from django.http import Http404, HttpResponse, HttpResponseRedirect 8 from django.core.exceptions import ObjectDoesNotExist, ImproperlyConfigured9 7 from django.utils.translation import gettext 8 from django.template import RequestContext, loader 10 9 11 def create_object(request, model, template_name=None, 12 template_loader=loader, extra_context=None, post_save_redirect=None, 13 login_required=False, follow=None, context_processors=None): 10 11 def create_object(request, model, 12 template_name=None, template_loader=loader, 13 extra_context=None, post_save_redirect=None, 14 login_required=False, context_processors=None, 15 not_required_fields=None, hidden_fields=None, 16 default_data=None, choices=None): 14 17 """ 15 18 Generic object-creation function. 16 19 … … 19 22 form 20 23 the form wrapper for the object 21 24 """ 22 if extra_context is None: extra_context = {}23 25 if login_required and not request.user.is_authenticated(): 24 26 return redirect_to_login(request.path) 25 27 26 manipulator = model.AddManipulator(follow=follow)27 if request. POST:28 # If data was POSTed, we're trying to create a new object28 FormClass = forms.models.form_for_model(model) 29 if request.method == 'POST': 30 # Create a form with POSTed data 29 31 new_data = request.POST.copy() 30 32 31 33 if model._meta.has_field_type(FileField): 32 34 new_data.update(request.FILES) 33 35 34 # Check for errors 35 errors = manipulator.get_validation_errors(new_data) 36 manipulator.do_html2python(new_data) 36 form = FormClass(new_data) 37 37 38 if not errors: 39 # No errors -- this means we can save the data! 40 new_object = manipulator.save(new_data) 38 else: 39 # Create new form with default data 40 if default_data is None: default_data = {} 41 form = FormClass(default_data) 41 42 42 if request.user.is_authenticated(): 43 request.user.message_set.create(message=gettext("The %(verbose_name)s was created successfully.") % {"verbose_name": model._meta.verbose_name}) 43 # Modify choices 44 if choices: 45 for field in choices.keys(): 46 if not form.fields.has_key(field): raise FieldDoesNotExist 47 form.fields[field] = forms.ChoiceField(choices[field]) 44 48 45 # Redirect to the new object: first by trying post_save_redirect, 46 # then by obj.get_absolute_url; fail if neither works. 47 if post_save_redirect: 48 return HttpResponseRedirect(post_save_redirect % new_object.__dict__) 49 elif hasattr(new_object, 'get_absolute_url'): 50 return HttpResponseRedirect(new_object.get_absolute_url()) 51 else: 52 raise ImproperlyConfigured("No URL to redirect to from generic create view.") 53 else: 54 # No POST, so we want a brand new form without any data or errors 55 errors = {} 56 new_data = manipulator.flatten_data() 49 # Mark some fields as 'hidden' 50 if hidden_fields: 51 for (field, value) in hidden_fields.iteritems(): 52 if not form.fields.has_key(field): raise FieldDoesNotExist 53 form.fields[field].widget = forms.HiddenInput() 54 # Prevent hidden field from being modified 55 form.data[field] = value 56 # Empty hidden fields are supposed not to be required 57 if value == "": form.fields[field].required = False 57 58 58 # Create the FormWrapper, template, context, response 59 form = oldforms.FormWrapper(manipulator, new_data, errors) 60 if not template_name: 59 # Mark some fields as 'not required' 60 if not_required_fields: 61 for field in not_required_fields: 62 if not form.fields.has_key(field): raise FieldDoesNotExist 63 form.fields[field].required = False 64 65 if request.method == 'POST' and not form.errors: 66 # Form does't contain errors, save the data 67 new_object = form.save() 68 69 if request.user.is_authenticated(): 70 request.user.message_set.create(message=gettext("The %(verbose_name)s was created successfully.") % {"verbose_name": model._meta.verbose_name}) 71 72 # Redirect to the new object: first by trying post_save_redirect, 73 # then by obj.get_absolute_url; fail if neither works. 74 if post_save_redirect: 75 return HttpResponseRedirect(post_save_redirect % new_object.__dict__) 76 elif hasattr(new_object, 'get_absolute_url'): 77 return HttpResponseRedirect(new_object.get_absolute_url()) 78 else: 79 raise ImproperlyConfigured("No URL to redirect to from generic create view.") 80 81 # Create template 82 if template_name is None: 61 83 template_name = "%s/%s_form.html" % (model._meta.app_label, model._meta.object_name.lower()) 62 84 t = template_loader.get_template(template_name) 85 86 # Create context 63 87 c = RequestContext(request, { 64 88 'form': form, 65 89 }, context_processors) 66 for key, value in extra_context.items(): 67 if callable(value): 68 c[key] = value() 69 else: 70 c[key] = value 90 91 # Add extra context 92 if extra_context: 93 for key, value in extra_context.items(): 94 if callable(value): 95 c[key] = value() 96 else: 97 c[key] = value 98 99 # Render template and return the response 71 100 return HttpResponse(t.render(c)) 72 101 73 def update_object(request, model, object_id=None, slug=None, 74 slug_field=None, template_name=None, template_loader=loader, 75 extra_context=None, post_save_redirect=None, 76 login_required=False, follow=None, context_processors=None, 77 template_object_name='object'): 102 103 def update_object(request, model, 104 object_id=None, slug=None, slug_field=None, 105 template_name=None, template_loader=loader, 106 template_object_name='object', 107 extra_context=None, context_processors=None, 108 post_save_redirect=None, login_required=False, 109 not_required_fields=None, hidden_fields=None, 110 choices=None): 111 78 112 """ 79 113 Generic object-update function. 80 114 … … 85 119 object 86 120 the original object being edited 87 121 """ 88 if extra_context is None: extra_context = {}89 122 if login_required and not request.user.is_authenticated(): 90 123 return redirect_to_login(request.path) 91 124 … … 97 130 lookup_kwargs['%s__exact' % slug_field] = slug 98 131 else: 99 132 raise AttributeError("Generic edit view must be called with either an object_id or a slug/slug_field") 133 100 134 try: 101 135 object = model.objects.get(**lookup_kwargs) 102 136 except ObjectDoesNotExist: 103 137 raise Http404, "No %s found for %s" % (model._meta.verbose_name, lookup_kwargs) 104 138 105 manipulator = model.ChangeManipulator(getattr(object, object._meta.pk.attname), follow=follow) 139 FormClass = forms.models.form_for_instance(object) 140 if request.method == 'POST': 141 # Create a form with POSTed data 142 new_data = request.POST.copy() 106 143 107 if request.POST:108 new_data = request.POST.copy()109 144 if model._meta.has_field_type(FileField): 110 145 new_data.update(request.FILES) 111 errors = manipulator.get_validation_errors(new_data)112 manipulator.do_html2python(new_data)113 if not errors:114 object = manipulator.save(new_data)115 146 116 if request.user.is_authenticated(): 117 request.user.message_set.create(message=gettext("The %(verbose_name)s was updated successfully.") % {"verbose_name": model._meta.verbose_name}) 147 form = FormClass(new_data) 118 148 119 # Do a post-after-redirect so that reload works, etc.120 if post_save_redirect:121 return HttpResponseRedirect(post_save_redirect % object.__dict__)122 elif hasattr(object, 'get_absolute_url'):123 return HttpResponseRedirect(object.get_absolute_url())124 else:125 raise ImproperlyConfigured("No URL to redirect to from generic create view.")126 149 else: 127 errors = {} 128 # This makes sure the form acurate represents the fields of the place. 129 new_data = manipulator.flatten_data() 150 # Create a form with original object data 151 form = FormClass() 130 152 131 form = oldforms.FormWrapper(manipulator, new_data, errors) 153 # Modify choices 154 if choices: 155 for field in choices.keys(): 156 if not form.fields.has_key(field): raise FieldDoesNotExist 157 form.fields[field] = forms.ChoiceField(choices[field]) 158 159 # Mark some fields as 'hidden' 160 if hidden_fields: 161 for (field, value) in hidden_fields.iteritems(): 162 if not form.fields.has_key(field): raise FieldDoesNotExist 163 form.fields[field].widget = forms.HiddenInput() 164 # Prevent hidden field from being modified 165 form.data[field] = value 166 # Empty hidden fields are supposed not to be required 167 if value == "": form.fields[field].required = False 168 169 # Mark some fields as 'not required' 170 if not_required_fields: 171 for field in not_required_fields: 172 if not form.fields.has_key(field): raise FieldDoesNotExist 173 form.fields[field].required = False 174 175 if request.method == 'POST' and not form.errors: 176 object = form.save(new_data) 177 178 if request.user.is_authenticated(): 179 request.user.message_set.create(message=gettext("The %(verbose_name)s was updated successfully.") % {"verbose_name": model._meta.verbose_name}) 180 181 # Do a post-after-redirect so that reload works, etc. 182 if post_save_redirect: 183 return HttpResponseRedirect(post_save_redirect % object.__dict__) 184 elif hasattr(object, 'get_absolute_url'): 185 return HttpResponseRedirect(object.get_absolute_url()) 186 else: 187 raise ImproperlyConfigured("No URL to redirect to from generic create view.") 188 189 # Create template 132 190 if not template_name: 133 191 template_name = "%s/%s_form.html" % (model._meta.app_label, model._meta.object_name.lower()) 134 192 t = template_loader.get_template(template_name) 193 194 # Create context 135 195 c = RequestContext(request, { 136 196 'form': form, 137 197 template_object_name: object, 138 198 }, context_processors) 139 for key, value in extra_context.items(): 140 if callable(value): 141 c[key] = value() 142 else: 143 c[key] = value 199 200 # Add extra context 201 if extra_context: 202 for key, value in extra_context.items(): 203 if callable(value): 204 c[key] = value() 205 else: 206 c[key] = value 207 208 # Render template and return the response 144 209 response = HttpResponse(t.render(c)) 145 210 populate_xheaders(request, response, model, getattr(object, object._meta.pk.attname)) 146 211 return response 147 212 213 148 214 def delete_object(request, model, post_delete_redirect, 149 object_id=None, slug=None, slug_field=None, template_name=None, 150 template_loader=loader, extra_context=None, 151 login_required=False, context_processors=None, template_object_name='object'): 215 object_id=None, slug=None, slug_field=None, 216 template_name=None, template_loader=loader, 217 template_object_name='object', login_required=False, 218 extra_context=None, context_processors=None): 152 219 """ 153 220 Generic object-delete function. 154 221 … … 161 228 object 162 229 the original object being deleted 163 230 """ 164 if extra_context is None: extra_context = {}165 231 if login_required and not request.user.is_authenticated(): 166 232 return redirect_to_login(request.path) 167 233 … … 173 239 lookup_kwargs['%s__exact' % slug_field] = slug 174 240 else: 175 241 raise AttributeError("Generic delete view must be called with either an object_id or a slug/slug_field") 242 176 243 try: 177 244 object = model._default_manager.get(**lookup_kwargs) 178 245 except ObjectDoesNotExist: … … 183 250 if request.user.is_authenticated(): 184 251 request.user.message_set.create(message=gettext("The %(verbose_name)s was deleted.") % {"verbose_name": model._meta.verbose_name}) 185 252 return HttpResponseRedirect(post_delete_redirect) 253 186 254 else: 255 # Create template 187 256 if not template_name: 188 template_name = "%s/%s_ confirm_delete.html" % (model._meta.app_label, model._meta.object_name.lower())257 template_name = "%s/%s_delete.html" % (model._meta.app_label, model._meta.object_name.lower()) 189 258 t = template_loader.get_template(template_name) 259 260 # Create context 190 261 c = RequestContext(request, { 191 262 template_object_name: object, 192 263 }, context_processors) 193 for key, value in extra_context.items(): 194 if callable(value): 195 c[key] = value() 196 else: 197 c[key] = value 264 265 # Add extra context 266 if extra_context: 267 for key, value in extra_context.items(): 268 if callable(value): 269 c[key] = value() 270 else: 271 c[key] = value 272 273 # Render template and return the response 198 274 response = HttpResponse(t.render(c)) 199 275 populate_xheaders(request, response, model, getattr(object, object._meta.pk.attname)) 200 276 return response