Changeset 7979 for django/branches/gis/django/views
- Timestamp:
- 07/19/08 08:30:47 (6 months ago)
- Files:
-
- django/branches/gis (modified) (1 prop)
- django/branches/gis/django/views/debug.py (modified) (3 diffs)
- django/branches/gis/django/views/generic/create_update.py (modified) (7 diffs)
- django/branches/gis/django/views/generic/__init__.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/branches/gis
- Property svnmerge-integrated changed from /django/trunk:1-7917 to /django/trunk:1-7978
django/branches/gis/django/views/debug.py
r7918 r7979 19 19 p = template_source.find('\n', p+1) 20 20 yield len(template_source) + 1 21 22 def get_template_exception_info(exc_type, exc_value, tb):23 origin, (start, end) = exc_value.source24 template_source = origin.reload()25 context_lines = 1026 line = 027 upto = 028 source_lines = []29 before = during = after = ""30 for num, next in enumerate(linebreak_iter(template_source)):31 if start >= upto and end <= next:32 line = num33 before = escape(template_source[upto:start])34 during = escape(template_source[start:end])35 after = escape(template_source[end:next])36 source_lines.append( (num, escape(template_source[upto:next])) )37 upto = next38 total = len(source_lines)39 40 top = max(1, line - context_lines)41 bottom = min(total, line + 1 + context_lines)42 43 template_info = {44 'message': exc_value.args[0],45 'source_lines': source_lines[top:bottom],46 'before': before,47 'during': during,48 'after': after,49 'top': top,50 'bottom': bottom,51 'total': total,52 'line': line,53 'name': origin.name,54 }55 exc_info = hasattr(exc_value, 'exc_info') and exc_value.exc_info or (exc_type, exc_value, tb)56 return exc_info + (template_info,)57 21 58 22 def get_safe_settings(): … … 72 36 the values returned from sys.exc_info() and friends. 73 37 """ 74 html = get_traceback_html(request, exc_type, exc_value, tb) 38 reporter = ExceptionReporter(request, exc_type, exc_value, tb) 39 html = reporter.get_traceback_html() 75 40 return HttpResponseServerError(html, mimetype='text/html') 76 41 77 def get_traceback_html(request, exc_type, exc_value, tb): 78 "Return HTML code for traceback." 79 template_info = None 80 template_does_not_exist = False 81 loader_debug_info = None 82 83 # Handle deprecated string exceptions 84 if isinstance(exc_type, basestring): 85 exc_value = Exception('Deprecated String Exception: %r' % exc_type) 86 exc_type = type(exc_value) 87 88 if issubclass(exc_type, TemplateDoesNotExist): 89 from django.template.loader import template_source_loaders 90 template_does_not_exist = True 91 loader_debug_info = [] 92 for loader in template_source_loaders: 42 class ExceptionReporter: 43 """ 44 A class to organize and coordinate reporting on exceptions. 45 """ 46 def __init__(self, request, exc_type, exc_value, tb): 47 self.request = request 48 self.exc_type = exc_type 49 self.exc_value = exc_value 50 self.tb = tb 51 52 self.template_info = None 53 self.template_does_not_exist = False 54 self.loader_debug_info = None 55 56 # Handle deprecated string exceptions 57 if isinstance(self.exc_type, basestring): 58 self.exc_value = Exception('Deprecated String Exception: %r' % self.exc_type) 59 self.exc_type = type(self.exc_value) 60 61 def get_traceback_html(self): 62 "Return HTML code for traceback." 63 64 if issubclass(self.exc_type, TemplateDoesNotExist): 65 from django.template.loader import template_source_loaders 66 self.template_does_not_exist = True 67 self.loader_debug_info = [] 68 for loader in template_source_loaders: 69 try: 70 source_list_func = getattr(__import__(loader.__module__, {}, {}, ['get_template_sources']), 'get_template_sources') 71 # NOTE: This assumes exc_value is the name of the template that 72 # the loader attempted to load. 73 template_list = [{'name': t, 'exists': os.path.exists(t)} \ 74 for t in source_list_func(str(self.exc_value))] 75 except (ImportError, AttributeError): 76 template_list = [] 77 self.loader_debug_info.append({ 78 'loader': loader.__module__ + '.' + loader.__name__, 79 'templates': template_list, 80 }) 81 if settings.TEMPLATE_DEBUG and hasattr(self.exc_value, 'source'): 82 self.get_template_exception_info() 83 84 frames = self.get_traceback_frames() 85 86 unicode_hint = '' 87 if issubclass(self.exc_type, UnicodeError): 88 start = getattr(self.exc_value, 'start', None) 89 end = getattr(self.exc_value, 'end', None) 90 if start is not None and end is not None: 91 unicode_str = self.exc_value.args[1] 92 unicode_hint = smart_unicode(unicode_str[max(start-5, 0):min(end+5, len(unicode_str))], 'ascii', errors='replace') 93 from django import get_version 94 t = Template(TECHNICAL_500_TEMPLATE, name='Technical 500 template') 95 c = Context({ 96 'exception_type': self.exc_type.__name__, 97 'exception_value': smart_unicode(self.exc_value, errors='replace'), 98 'unicode_hint': unicode_hint, 99 'frames': frames, 100 'lastframe': frames[-1], 101 'request': self.request, 102 'request_protocol': self.request.is_secure() and "https" or "http", 103 'settings': get_safe_settings(), 104 'sys_executable': sys.executable, 105 'sys_version_info': '%d.%d.%d' % sys.version_info[0:3], 106 'server_time': datetime.datetime.now(), 107 'django_version_info': get_version(), 108 'sys_path' : sys.path, 109 'template_info': self.template_info, 110 'template_does_not_exist': self.template_does_not_exist, 111 'loader_debug_info': self.loader_debug_info, 112 }) 113 return t.render(c) 114 115 def get_template_exception_info(self): 116 origin, (start, end) = self.exc_value.source 117 template_source = origin.reload() 118 context_lines = 10 119 line = 0 120 upto = 0 121 source_lines = [] 122 before = during = after = "" 123 for num, next in enumerate(linebreak_iter(template_source)): 124 if start >= upto and end <= next: 125 line = num 126 before = escape(template_source[upto:start]) 127 during = escape(template_source[start:end]) 128 after = escape(template_source[end:next]) 129 source_lines.append( (num, escape(template_source[upto:next])) ) 130 upto = next 131 total = len(source_lines) 132 133 top = max(1, line - context_lines) 134 bottom = min(total, line + 1 + context_lines) 135 136 self.template_info = { 137 'message': self.exc_value.args[0], 138 'source_lines': source_lines[top:bottom], 139 'before': before, 140 'during': during, 141 'after': after, 142 'top': top, 143 'bottom': bottom, 144 'total': total, 145 'line': line, 146 'name': origin.name, 147 } 148 if hasattr(self.exc_value, 'exc_info') and self.exc_value.exc_info: 149 exc_type, exc_value, tb = self.exc_value.exc_info 150 151 def _get_lines_from_file(self, filename, lineno, context_lines, loader=None, module_name=None): 152 """ 153 Returns context_lines before and after lineno from file. 154 Returns (pre_context_lineno, pre_context, context_line, post_context). 155 """ 156 source = None 157 if loader is not None and hasattr(loader, "get_source"): 158 source = loader.get_source(module_name) 159 if source is not None: 160 source = source.splitlines() 161 if source is None: 93 162 try: 94 source_list_func = getattr(__import__(loader.__module__, {}, {}, ['get_template_sources']), 'get_template_sources') 95 # NOTE: This assumes exc_value is the name of the template that 96 # the loader attempted to load. 97 template_list = [{'name': t, 'exists': os.path.exists(t)} \ 98 for t in source_list_func(str(exc_value))] 99 except (ImportError, AttributeError): 100 template_list = [] 101 loader_debug_info.append({ 102 'loader': loader.__module__ + '.' + loader.__name__, 103 'templates': template_list, 104 }) 105 if settings.TEMPLATE_DEBUG and hasattr(exc_value, 'source'): 106 exc_type, exc_value, tb, template_info = get_template_exception_info(exc_type, exc_value, tb) 107 frames = [] 108 while tb is not None: 109 # support for __traceback_hide__ which is used by a few libraries 110 # to hide internal frames. 111 if tb.tb_frame.f_locals.get('__traceback_hide__'): 163 f = open(filename) 164 try: 165 source = f.readlines() 166 finally: 167 f.close() 168 except (OSError, IOError): 169 pass 170 if source is None: 171 return None, [], None, [] 172 173 encoding = 'ascii' 174 for line in source[:2]: 175 # File coding may be specified. Match pattern from PEP-263 176 # (http://www.python.org/dev/peps/pep-0263/) 177 match = re.search(r'coding[:=]\s*([-\w.]+)', line) 178 if match: 179 encoding = match.group(1) 180 break 181 source = [unicode(sline, encoding, 'replace') for sline in source] 182 183 lower_bound = max(0, lineno - context_lines) 184 upper_bound = lineno + context_lines 185 186 pre_context = [line.strip('\n') for line in source[lower_bound:lineno]] 187 context_line = source[lineno].strip('\n') 188 post_context = [line.strip('\n') for line in source[lineno+1:upper_bound]] 189 190 return lower_bound, pre_context, context_line, post_context 191 192 def get_traceback_frames(self): 193 frames = [] 194 tb = self.tb 195 while tb is not None: 196 # support for __traceback_hide__ which is used by a few libraries 197 # to hide internal frames. 198 if tb.tb_frame.f_locals.get('__traceback_hide__'): 199 tb = tb.tb_next 200 continue 201 filename = tb.tb_frame.f_code.co_filename 202 function = tb.tb_frame.f_code.co_name 203 lineno = tb.tb_lineno - 1 204 loader = tb.tb_frame.f_globals.get('__loader__') 205 module_name = tb.tb_frame.f_globals.get('__name__') 206 pre_context_lineno, pre_context, context_line, post_context = self._get_lines_from_file(filename, lineno, 7, loader, module_name) 207 if pre_context_lineno is not None: 208 frames.append({ 209 'tb': tb, 210 'filename': filename, 211 'function': function, 212 'lineno': lineno + 1, 213 'vars': tb.tb_frame.f_locals.items(), 214 'id': id(tb), 215 'pre_context': pre_context, 216 'context_line': context_line, 217 'post_context': post_context, 218 'pre_context_lineno': pre_context_lineno + 1, 219 }) 112 220 tb = tb.tb_next 113 continue 114 filename = tb.tb_frame.f_code.co_filename 115 function = tb.tb_frame.f_code.co_name 116 lineno = tb.tb_lineno - 1 117 loader = tb.tb_frame.f_globals.get('__loader__') 118 module_name = tb.tb_frame.f_globals.get('__name__') 119 pre_context_lineno, pre_context, context_line, post_context = _get_lines_from_file(filename, lineno, 7, loader, module_name) 120 if pre_context_lineno is not None: 121 frames.append({ 122 'tb': tb, 123 'filename': filename, 124 'function': function, 125 'lineno': lineno + 1, 126 'vars': tb.tb_frame.f_locals.items(), 127 'id': id(tb), 128 'pre_context': pre_context, 129 'context_line': context_line, 130 'post_context': post_context, 131 'pre_context_lineno': pre_context_lineno + 1, 132 }) 133 tb = tb.tb_next 134 135 if not frames: 136 frames = [{ 137 'filename': '<unknown>', 138 'function': '?', 139 'lineno': '?', 140 }] 141 142 unicode_hint = '' 143 if issubclass(exc_type, UnicodeError): 144 start = getattr(exc_value, 'start', None) 145 end = getattr(exc_value, 'end', None) 146 if start is not None and end is not None: 147 unicode_str = exc_value.args[1] 148 unicode_hint = smart_unicode(unicode_str[max(start-5, 0):min(end+5, len(unicode_str))], 'ascii', errors='replace') 149 from django import get_version 150 t = Template(TECHNICAL_500_TEMPLATE, name='Technical 500 template') 151 c = Context({ 152 'exception_type': exc_type.__name__, 153 'exception_value': smart_unicode(exc_value, errors='replace'), 154 'unicode_hint': unicode_hint, 155 'frames': frames, 156 'lastframe': frames[-1], 157 'request': request, 158 'request_protocol': request.is_secure() and "https" or "http", 159 'settings': get_safe_settings(), 160 'sys_executable': sys.executable, 161 'sys_version_info': '%d.%d.%d' % sys.version_info[0:3], 162 'server_time': datetime.datetime.now(), 163 'django_version_info': get_version(), 164 'sys_path' : sys.path, 165 'template_info': template_info, 166 'template_does_not_exist': template_does_not_exist, 167 'loader_debug_info': loader_debug_info, 168 }) 169 return t.render(c) 221 222 if not frames: 223 frames = [{ 224 'filename': '<unknown>', 225 'function': '?', 226 'lineno': '?', 227 'context_line': '???', 228 }] 229 230 return frames 231 232 def format_exception(self): 233 """ 234 Return the same data as from traceback.format_exception. 235 """ 236 import traceback 237 frames = self.get_traceback_frames() 238 tb = [ (f['filename'], f['lineno'], f['function'], f['context_line']) for f in frames ] 239 list = ['Traceback (most recent call last):\n'] 240 list += traceback.format_list(tb) 241 list += traceback.format_exception_only(self.exc_type, self.exc_value) 242 return list 243 170 244 171 245 def technical_404_response(request, exception): … … 199 273 }) 200 274 return HttpResponse(t.render(c), mimetype='text/html') 201 202 def _get_lines_from_file(filename, lineno, context_lines, loader=None, module_name=None):203 """204 Returns context_lines before and after lineno from file.205 Returns (pre_context_lineno, pre_context, context_line, post_context).206 """207 source = None208 if loader is not None and hasattr(loader, "get_source"):209 source = loader.get_source(module_name)210 if source is not None:211 source = source.splitlines()212 if source is None:213 try:214 f = open(filename)215 try:216 source = f.readlines()217 finally:218 f.close()219 except (OSError, IOError):220 pass221 if source is None:222 return None, [], None, []223 224 encoding = 'ascii'225 for line in source[:2]:226 # File coding may be specified. Match pattern from PEP-263227 # (http://www.python.org/dev/peps/pep-0263/)228 match = re.search(r'coding[:=]\s*([-\w.]+)', line)229 if match:230 encoding = match.group(1)231 break232 source = [unicode(sline, encoding, 'replace') for sline in source]233 234 lower_bound = max(0, lineno - context_lines)235 upper_bound = lineno + context_lines236 237 pre_context = [line.strip('\n') for line in source[lower_bound:lineno]]238 context_line = source[lineno].strip('\n')239 post_context = [line.strip('\n') for line in source[lineno+1:upper_bound]]240 241 return lower_bound, pre_context, context_line, post_context242 275 243 276 # django/branches/gis/django/views/generic/create_update.py
r6018 r7979 1 from django.forms.models import ModelFormMetaclass, ModelForm 2 from django.template import RequestContext, loader 3 from django.http import Http404, HttpResponse, HttpResponseRedirect 1 4 from django.core.xheaders import populate_xheaders 2 from django.template import loader3 from django import oldforms4 from django.db.models import FileField5 from django.contrib.auth.views import redirect_to_login6 from django.template import RequestContext7 from django.http import Http404, HttpResponse, HttpResponseRedirect8 5 from django.core.exceptions import ObjectDoesNotExist, ImproperlyConfigured 9 6 from django.utils.translation import ugettext 10 11 def create_object(request, model, template_name=None, 7 from django.contrib.auth.views import redirect_to_login 8 from django.views.generic import GenericViewError 9 10 def deprecate_follow(follow): 11 """ 12 Issues a DeprecationWarning if follow is anything but None. 13 14 The old Manipulator-based forms used a follow argument that is no longer 15 needed for newforms-based forms. 16 """ 17 if follow is not None: 18 import warning 19 msg = ("Generic views have been changed to use newforms, and the" 20 "'follow' argument is no longer used. Please update your code" 21 "to not use the 'follow' argument.") 22 warning.warn(msg, DeprecationWarning, stacklevel=3) 23 24 def apply_extra_context(extra_context, context): 25 """ 26 Adds items from extra_context dict to context. If a value in extra_context 27 is callable, then it is called and the result is added to context. 28 """ 29 for key, value in extra_context.iteritems(): 30 if callable(value): 31 context[key] = value() 32 else: 33 context[key] = value 34 35 def get_model_and_form_class(model, form_class): 36 """ 37 Returns a model and form class based on the model and form_class 38 parameters that were passed to the generic view. 39 40 If ``form_class`` is given then its associated model will be returned along 41 with ``form_class`` itself. Otherwise, if ``model`` is given, ``model`` 42 itself will be returned along with a ``ModelForm`` class created from 43 ``model``. 44 """ 45 if form_class: 46 return form_class._meta.model, form_class 47 if model: 48 # The inner Meta class fails if model = model is used for some reason. 49 tmp_model = model 50 # TODO: we should be able to construct a ModelForm without creating 51 # and passing in a temporary inner class. 52 class Meta: 53 model = tmp_model 54 class_name = model.__name__ + 'Form' 55 form_class = ModelFormMetaclass(class_name, (ModelForm,), {'Meta': Meta}) 56 return model, form_class 57 raise GenericViewError("Generic view must be called with either a model or" 58 " form_class argument.") 59 60 def redirect(post_save_redirect, obj): 61 """ 62 Returns a HttpResponseRedirect to ``post_save_redirect``. 63 64 ``post_save_redirect`` should be a string, and can contain named string- 65 substitution place holders of ``obj`` field names. 66 67 If ``post_save_redirect`` is None, then redirect to ``obj``'s URL returned 68 by ``get_absolute_url()``. If ``obj`` has no ``get_absolute_url`` method, 69 then raise ImproperlyConfigured. 70 71 This function is meant to handle the post_save_redirect parameter to the 72 ``create_object`` and ``update_object`` views. 73 """ 74 if post_save_redirect: 75 return HttpResponseRedirect(post_save_redirect % obj.__dict__) 76 elif hasattr(obj, 'get_absolute_url'): 77 return HttpResponseRedirect(obj.get_absolute_url()) 78 else: 79 raise ImproperlyConfigured( 80 "No URL to redirect to. Either pass a post_save_redirect" 81 " parameter to the generic view or define a get_absolute_url" 82 " method on the Model.") 83 84 def lookup_object(model, object_id, slug, slug_field): 85 """ 86 Return the ``model`` object with the passed ``object_id``. If 87 ``object_id`` is None, then return the the object whose ``slug_field`` 88 equals the passed ``slug``. If ``slug`` and ``slug_field`` are not passed, 89 then raise Http404 exception. 90 """ 91 lookup_kwargs = {} 92 if object_id: 93 lookup_kwargs['%s__exact' % model._meta.pk.name] = object_id 94 elif slug and slug_field: 95 lookup_kwargs['%s__exact' % slug_field] = slug 96 else: 97 raise GenericViewError( 98 "Generic view must be called with either an object_id or a" 99 " slug/slug_field.") 100 try: 101 return model.objects.get(**lookup_kwargs) 102 except ObjectDoesNotExist: 103 raise Http404("No %s found for %s" 104 % (model._meta.verbose_name, lookup_kwargs)) 105 106 def create_object(request, model=None, template_name=None, 12 107 template_loader=loader, extra_context=None, post_save_redirect=None, 13 login_required=False, follow=None, context_processors=None): 108 login_required=False, follow=None, context_processors=None, 109 form_class=None): 14 110 """ 15 111 Generic object-creation function. … … 18 114 Context: 19 115 form 20 the form wrapper for the object 21 """ 116 the form for the object 117 """ 118 deprecate_follow(follow) 22 119 if extra_context is None: extra_context = {} 23 120 if login_required and not request.user.is_authenticated(): 24 121 return redirect_to_login(request.path) 25 122 26 manipulator = model.AddManipulator(follow=follow) 27 if request.POST: 28 # If data was POSTed, we're trying to create a new object 29 new_data = request.POST.copy() 30 31 if model._meta.has_field_type(FileField): 32 new_data.update(request.FILES) 33 34 # Check for errors 35 errors = manipulator.get_validation_errors(new_data) 36 manipulator.do_html2python(new_data) 37 38 if not errors: 39 # No errors -- this means we can save the data! 40 new_object = manipulator.save(new_data) 41 123 model, form_class = get_model_and_form_class(model, form_class) 124 if request.method == 'POST': 125 form = form_class(request.POST, request.FILES) 126 if form.is_valid(): 127 new_object = form.save() 42 128 if request.user.is_authenticated(): 43 129 request.user.message_set.create(message=ugettext("The %(verbose_name)s was created successfully.") % {"verbose_name": model._meta.verbose_name}) 44 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() 57 58 # Create the FormWrapper, template, context, response 59 form = oldforms.FormWrapper(manipulator, new_data, errors) 130 return redirect(post_save_redirect, new_object) 131 else: 132 form = form_class() 133 134 # Create the template, context, response 60 135 if not template_name: 61 136 template_name = "%s/%s_form.html" % (model._meta.app_label, model._meta.object_name.lower()) … … 64 139 'form': form, 65 140 }, context_processors) 66 for key, value in extra_context.items(): 67 if callable(value): 68 c[key] = value() 69 else: 70 c[key] = value 141 apply_extra_context(extra_context, c) 71 142 return HttpResponse(t.render(c)) 72 143 73 def update_object(request, model , object_id=None, slug=None,144 def update_object(request, model=None, object_id=None, slug=None, 74 145 slug_field='slug', template_name=None, template_loader=loader, 75 146 extra_context=None, post_save_redirect=None, 76 147 login_required=False, follow=None, context_processors=None, 77 template_object_name='object' ):148 template_object_name='object', form_class=None): 78 149 """ 79 150 Generic object-update function. … … 82 153 Context: 83 154 form 84 the form wrapperfor the object155 the form for the object 85 156 object 86 157 the original object being edited 87 158 """ 159 deprecate_follow(follow) 88 160 if extra_context is None: extra_context = {} 89 161 if login_required and not request.user.is_authenticated(): 90 162 return redirect_to_login(request.path) 91 163 92 # Look up the object to be edited 93 lookup_kwargs = {} 94 if object_id: 95 lookup_kwargs['%s__exact' % model._meta.pk.name] = object_id 96 elif slug and slug_field: 97 lookup_kwargs['%s__exact' % slug_field] = slug 98 else: 99 raise AttributeError("Generic edit view must be called with either an object_id or a slug/slug_field") 100 try: 101 object = model.objects.get(**lookup_kwargs) 102 except ObjectDoesNotExist: 103 raise Http404, "No %s found for %s" % (model._meta.verbose_name, lookup_kwargs) 104 105 manipulator = model.ChangeManipulator(getattr(object, object._meta.pk.attname), follow=follow) 106 107 if request.POST: 108 new_data = request.POST.copy() 109 if model._meta.has_field_type(FileField): 110 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 164 model, form_class = get_model_and_form_class(model, form_class) 165 obj = lookup_object(model, object_id, slug, slug_field) 166 167 if request.method == 'POST': 168 form = form_class(request.POST, request.FILES, instance=obj) 169 if form.is_valid(): 170 obj = form.save() 116 171 if request.user.is_authenticated(): 117 172 request.user.message_set.create(message=ugettext("The %(verbose_name)s was updated successfully.") % {"verbose_name": model._meta.verbose_name}) 118 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 else: 127 errors = {} 128 # This makes sure the form acurate represents the fields of the place. 129 new_data = manipulator.flatten_data() 130 131 form = oldforms.FormWrapper(manipulator, new_data, errors) 173 return redirect(post_save_redirect, obj) 174 else: 175 form = form_class(instance=obj) 176 132 177 if not template_name: 133 178 template_name = "%s/%s_form.html" % (model._meta.app_label, model._meta.object_name.lower()) … … 135 180 c = RequestContext(request, { 136 181 'form': form, 137 template_object_name: obj ect,182 template_object_name: obj, 138 183 }, context_processors) 139 for key, value in extra_context.items(): 140 if callable(value): 141 c[key] = value() 142 else: 143 c[key] = value 184 apply_extra_context(extra_context, c) 144 185 response = HttpResponse(t.render(c)) 145 populate_xheaders(request, response, model, getattr(obj ect, object._meta.pk.attname))186 populate_xheaders(request, response, model, getattr(obj, obj._meta.pk.attname)) 146 187 return response 147 188 148 def delete_object(request, model, post_delete_redirect, 149 object_id=None,slug=None, slug_field='slug', template_name=None,150 template_loader=loader, extra_context=None, 151 login_required=False,context_processors=None, template_object_name='object'):189 def delete_object(request, model, post_delete_redirect, object_id=None, 190 slug=None, slug_field='slug', template_name=None, 191 template_loader=loader, extra_context=None, login_required=False, 192 context_processors=None, template_object_name='object'): 152 193 """ 153 194 Generic object-delete function. … … 166 207 return redirect_to_login(request.path) 167 208 168 # Look up the object to be edited 169 lookup_kwargs = {} 170 if object_id: 171 lookup_kwargs['%s__exact' % model._meta.pk.name] = object_id 172 elif slug and slug_field: 173 lookup_kwargs['%s__exact' % slug_field] = slug 174 else: 175 raise AttributeError("Generic delete view must be called with either an object_id or a slug/slug_field") 176 try: 177 object = model._default_manager.get(**lookup_kwargs) 178 except ObjectDoesNotExist: 179 raise Http404, "No %s found for %s" % (model._meta.app_label, lookup_kwargs) 209 obj = lookup_object(model, object_id, slug, slug_field) 180 210 181 211 if request.method == 'POST': 182 obj ect.delete()212 obj.delete() 183 213 if request.user.is_authenticated(): 184 214 request.user.message_set.create(message=ugettext("The %(verbose_name)s was deleted.") % {"verbose_name": model._meta.verbose_name}) … … 189 219 t = template_loader.get_template(template_name) 190 220 c = RequestContext(request, { 191 template_object_name: obj ect,221 template_object_name: obj, 192 222 }, context_processors) 193 for key, value in extra_context.items(): 194 if callable(value): 195 c[key] = value() 196 else: 197 c[key] = value 223 apply_extra_context(extra_context, c) 198 224 response = HttpResponse(t.render(c)) 199 populate_xheaders(request, response, model, getattr(obj ect, object._meta.pk.attname))225 populate_xheaders(request, response, model, getattr(obj, obj._meta.pk.attname)) 200 226 return response django/branches/gis/django/views/generic/__init__.py
r4265 r7979 1 class GenericViewError(Exception): 2 """A problem in a generic view.""" 3 pass
