""" views which implement generic 'tag aware' create/update views """ __revision__ = "$Rev$" __date__ = "$Date$" from django.core.xheaders import populate_xheaders from django.template import loader from django import forms from django.db.models import FileField from django.contrib.auth.views import redirect_to_login from django.template.defaultfilters import slugify from django.template import RequestContext from django.http import Http404, HttpResponse, HttpResponseRedirect from django.core.exceptions import ObjectDoesNotExist, ImproperlyConfigured import datetime from zilbo.common.utils.misc import get_content_type_id from zilbo.common.tag.models import TagObject, TagUserObject, Tag def create_tag_object(request, model, template_name=None, template_loader=loader, extra_context=None, post_save_redirect=None, follow=None, context_processors=None, mode='user'): """ Generic object-creation function. Templates: ``/_form.html`` Context: form the form wrapper for the object """ if extra_context is None: extra_context = {} if request.user.is_anonymous(): return redirect_to_login(request.path) manipulator = model.AddManipulator(follow=follow) if request.POST: # If data was POSTed, we're trying to create a new object new_data = request.POST.copy() now = datetime.datetime.today() if new_data.has_key('name'): new_data['slug'] = slugify(new_data['name']) new_data['last_change_user_id'] = str(request.user.id) new_data['last_change_user'] = new_data['last_change_user_id'] new_data['create_user_id'] = new_data['last_change_user_id'] new_data['create_user'] = new_data['last_change_user_id'] new_data['last_change_date'] = now.strftime('%Y-%m-%d') new_data['last_change_time'] = now.strftime('%H:%M:%S') new_data['creation_date_date'] = now.strftime('%Y-%m-%d') new_data['creation_date_time'] = now.strftime('%H:%M:%S') if model._meta.has_field_type(FileField): new_data.update(request.FILES) # Check for errors errors = manipulator.get_validation_errors(new_data) manipulator.do_html2python(new_data) if not errors: # No errors -- this means we can save the data! new_object = manipulator.save(new_data) if request.POST.has_key('tags'): tags = Tag.objects.create_from_string( request.user, request.POST['tags'] ) new_object.tags.clear() ct_id = get_content_type_id( new_object ) for i in tags: if mode == 'user': t = TagUserObject( tag_id = i.id, content_type_id = ct_id, object_id = new_object.id, user_id = request.user.id ) t.save() else: t = TagObject( tag_id = i.id, content_type_id = ct_id, object_id = new_object.id ) t.save() request.user.message_set.create(message="The %s was created successfully." % model._meta.verbose_name) # Redirect to the new object: first by trying post_save_redirect, # then by obj.get_absolute_url; fail if neither works. if post_save_redirect: return HttpResponseRedirect(post_save_redirect % new_object.__dict__) elif hasattr(new_object, 'get_absolute_url'): return HttpResponseRedirect(new_object.get_absolute_url()) else: raise ImproperlyConfigured("No URL to redirect to from generic create view.") else: # No POST, so we want a brand new form without any data or errors errors = {} new_data = manipulator.flatten_data() # Create the FormWrapper, template, context, response form = forms.FormWrapper(manipulator, new_data, errors) if not template_name: template_name = "%s/%s_form.html" % (model._meta.app_label, model._meta.object_name.lower()) t = template_loader.get_template(template_name) c = RequestContext(request, { 'form': form, }, context_processors) for key, value in extra_context.items(): if callable(value): c[key] = value() else: c[key] = value return HttpResponse(t.render(c)) def update_tag_object(request, model, object_id=None, slug=None, slug_field=None, template_name=None, template_loader=loader, extra_context=None, post_save_redirect=None, follow=None, context_processors=None, template_object_name='object', mode='user'): """ Generic object-update function. Templates: ``/_form.html`` Context: form the form wrapper for the object object the original object being edited """ if extra_context is None: extra_context = {} if request.user.is_anonymous(): return redirect_to_login(request.path) # Look up the object to be edited lookup_kwargs = {} if object_id: lookup_kwargs['%s__exact' % model._meta.pk.name] = object_id elif slug and slug_field: lookup_kwargs['%s__exact' % slug_field] = slug else: raise AttributeError("Generic edit view must be called with either an object_id or a slug/slug_field") try: object = model.objects.get(**lookup_kwargs) except ObjectDoesNotExist: raise Http404, "No %s found for %s" % (model._meta.verbose_name, lookup_kwargs) manipulator = model.ChangeManipulator(getattr(object, object._meta.pk.name), follow=follow) if request.POST: new_data = request.POST.copy() if model._meta.has_field_type(FileField): new_data.update(request.FILES) now = datetime.datetime.today() if new_data.has_key('name'): new_data['slug'] = slugify(new_data['name']) new_data['last_change_user_id'] = str(request.user.id) new_data['last_change_user'] = new_data['last_change_user_id'] new_data['last_change_date'] = now.strftime('%Y-%m-%d') new_data['last_change_time'] = now.strftime('%H:%M:%S') new_data['create_user_id'] = str(object.create_user.id) new_data['create_user'] = new_data['create_user_id'] new_data['creation_date_date'] = object.creation_date.strftime('%Y-%m-%d') new_data['creation_date_time'] = object.creation_date.strftime('%H:%M:%S') errors = manipulator.get_validation_errors(new_data) manipulator.do_html2python(new_data) if not errors: object = manipulator.save(new_data) if request.POST.has_key('tags'): tags = Tag.objects.create_from_string( request.user, request.POST['tags'] ) object.tags.clear() ct_id = get_content_type_id( object ) for i in tags: if mode == 'user': t = TagUserObject( tag_id = i.id, content_type_id = ct_id, object_id = object.id, user_id = request.user.id ) t.save() else: t = TagObject( tag_id = i.id, content_type_id = ct_id, object_id = object.id ) t.save() request.user.message_set.create(message="The %s was updated successfully." % model._meta.verbose_name) # Do a post-after-redirect so that reload works, etc. if post_save_redirect: return HttpResponseRedirect(post_save_redirect % object.__dict__) elif hasattr(object, 'get_absolute_url'): return HttpResponseRedirect(object.get_absolute_url()) else: raise ImproperlyConfigured("No URL to redirect to from generic create view.") else: errors = {} # This makes sure the form acurate represents the fields of the place. new_data = manipulator.flatten_data() form = forms.FormWrapper(manipulator, new_data, errors) if not template_name: template_name = "%s/%s_form.html" % (model._meta.app_label, model._meta.object_name.lower()) t = template_loader.get_template(template_name) c = RequestContext(request, { 'form': form, template_object_name: object, }, context_processors) for key, value in extra_context.items(): if callable(value): c[key] = value() else: c[key] = value response = HttpResponse(t.render(c)) populate_xheaders(request, response, model, getattr(object, object._meta.pk.name)) return response