| | 281 | def check_dependancies(self): |
|---|
| | 282 | """ |
|---|
| | 283 | Check that all things needed to run the admin have been correctly installed. |
|---|
| | 284 | |
|---|
| | 285 | The default implementation checks that LogEntry, ContentType and the |
|---|
| | 286 | auth context processor are installed. |
|---|
| | 287 | """ |
|---|
| | 288 | from django.conf import settings |
|---|
| | 289 | from django.contrib.admin.models import LogEntry |
|---|
| | 290 | |
|---|
| | 291 | if not LogEntry._meta.installed: |
|---|
| | 292 | raise ImproperlyConfigured("Put 'django.contrib.admin' in your INSTALLED_APPS setting in order to use the admin application.") |
|---|
| | 293 | if not ContentType._meta.installed: |
|---|
| | 294 | raise ImproperlyConfigured("Put 'django.contrib.contenttypes' in your INSTALLED_APPS setting in order to use the admin application.") |
|---|
| | 295 | if 'django.core.context_processors.auth' not in settings.TEMPLATE_CONTEXT_PROCESSORS: |
|---|
| | 296 | raise ImproperlyConfigured("Put 'django.core.context_processors.auth' in your TEMPLATE_CONTEXT_PROCESSORS setting in order to use the admin application.") |
|---|
| | 297 | |
|---|
| 370 | | opts = self.model._meta |
|---|
| 371 | | new_object = form.save(commit=True) |
|---|
| 372 | | |
|---|
| 373 | | if formsets: |
|---|
| 374 | | for formset in formsets: |
|---|
| 375 | | # HACK: it seems like the parent obejct should be passed into |
|---|
| 376 | | # a method of something, not just set as an attribute |
|---|
| 377 | | formset.instance = new_object |
|---|
| 378 | | formset.save() |
|---|
| 379 | | |
|---|
| 380 | | pk_value = new_object._get_pk_val() |
|---|
| 381 | | LogEntry.objects.log_action(request.user.id, ContentType.objects.get_for_model(self.model).id, pk_value, force_unicode(new_object), ADDITION) |
|---|
| 382 | | msg = _('The %(name)s "%(obj)s" was added successfully.') % {'name': force_unicode(opts.verbose_name), 'obj': force_unicode(new_object)} |
|---|
| 383 | | # Here, we distinguish between different save types by checking for |
|---|
| 384 | | # the presence of keys in request.POST. |
|---|
| 385 | | if request.POST.has_key("_continue"): |
|---|
| 386 | | request.user.message_set.create(message=msg + ' ' + _("You may edit it again below.")) |
|---|
| 387 | | if request.POST.has_key("_popup"): |
|---|
| 388 | | post_url_continue += "?_popup=1" |
|---|
| 389 | | return HttpResponseRedirect(post_url_continue % pk_value) |
|---|
| 390 | | |
|---|
| 391 | | if request.POST.has_key("_popup"): |
|---|
| 392 | | return HttpResponse('<script type="text/javascript">opener.dismissAddAnotherPopup(window, "%s", "%s");</script>' % \ |
|---|
| 393 | | # escape() calls force_unicode. |
|---|
| 394 | | (escape(pk_value), escape(new_object))) |
|---|
| 395 | | elif request.POST.has_key("_addanother"): |
|---|
| 396 | | request.user.message_set.create(message=msg + ' ' + (_("You may add another %s below.") % force_unicode(opts.verbose_name))) |
|---|
| 397 | | return HttpResponseRedirect(request.path) |
|---|
| 398 | | else: |
|---|
| 399 | | request.user.message_set.create(message=msg) |
|---|
| 400 | | # Figure out where to redirect. If the user has change permission, |
|---|
| 401 | | # redirect to the change-list page for this object. Otherwise, |
|---|
| 402 | | # redirect to the admin index. |
|---|
| 403 | | if self.has_change_permission(request, None): |
|---|
| 404 | | post_url = '../' |
|---|
| 405 | | else: |
|---|
| 406 | | post_url = '../../../' |
|---|
| 407 | | return HttpResponseRedirect(post_url) |
|---|
| 408 | | save_add = transaction.commit_on_success(save_add) |
|---|
| 409 | | |
|---|
| 410 | | def save_change(self, request, form, formsets=None): |
|---|
| 411 | | """ |
|---|
| 412 | | Saves the object in the "change" stage and returns an HttpResponseRedirect. |
|---|
| 413 | | |
|---|
| 414 | | `form` is a bound Form instance that's verified to be valid. |
|---|
| 415 | | |
|---|
| 416 | | `formsets` is a sequence of InlineFormSet instances that are verified to be valid. |
|---|
| | 380 | LogEntry.objects.log_action( |
|---|
| | 381 | user_id = request.user.pk, |
|---|
| | 382 | content_type_id = ContentType.objects.get_for_model(object).pk, |
|---|
| | 383 | object_id = object.pk, |
|---|
| | 384 | object_repr = force_unicode(object), |
|---|
| | 385 | action_flag = ADDITION |
|---|
| | 386 | ) |
|---|
| | 387 | |
|---|
| | 388 | def log_change(self, request, object, message): |
|---|
| | 389 | """ |
|---|
| | 390 | Log that an object has been successfully changed. |
|---|
| | 391 | |
|---|
| | 392 | The default implementation creates an admin LogEntry object. |
|---|
| 419 | | opts = self.model._meta |
|---|
| 420 | | new_object = form.save(commit=True) |
|---|
| 421 | | pk_value = new_object._get_pk_val() |
|---|
| 422 | | |
|---|
| 423 | | if formsets: |
|---|
| 424 | | for formset in formsets: |
|---|
| 425 | | formset.save() |
|---|
| 426 | | |
|---|
| 427 | | # Construct the change message. |
|---|
| | 395 | LogEntry.objects.log_action( |
|---|
| | 396 | user_id = request.user.pk, |
|---|
| | 397 | content_type_id = ContentType.objects.get_for_model(object).pk, |
|---|
| | 398 | object_id = object.pk, |
|---|
| | 399 | object_repr = force_unicode(object), |
|---|
| | 400 | action_flag = CHANGE, |
|---|
| | 401 | change_message = message |
|---|
| | 402 | ) |
|---|
| | 403 | |
|---|
| | 404 | def log_deletion(self, request, object, object_repr): |
|---|
| | 405 | """ |
|---|
| | 406 | Log that an object has been successfully deleted. Note that since the |
|---|
| | 407 | object is deleted, it might no longer be safe to call *any* methods |
|---|
| | 408 | on the object, hence this method getting object_repr. |
|---|
| | 409 | |
|---|
| | 410 | The default implementation creates an admin LogEntry object. |
|---|
| | 411 | """ |
|---|
| | 412 | from django.contrib.admin.models import LogEntry, DELETION |
|---|
| | 413 | LogEntry.objects.log_action( |
|---|
| | 414 | user_id = request.user.id, |
|---|
| | 415 | content_type_id = ContentType.objects.get_for_model(self.model).pk, |
|---|
| | 416 | object_id = object.pk, |
|---|
| | 417 | object_repr = object_repr, |
|---|
| | 418 | action_flag = DELETION |
|---|
| | 419 | ) |
|---|
| | 420 | |
|---|
| | 421 | |
|---|
| | 422 | def construct_change_message(self, request, form, formsets): |
|---|
| | 423 | """ |
|---|
| | 424 | Construct a change message from a changed object. |
|---|
| | 425 | """ |
|---|
| 448 | | if not change_message: |
|---|
| 449 | | change_message = _('No fields changed.') |
|---|
| 450 | | LogEntry.objects.log_action(request.user.id, ContentType.objects.get_for_model(self.model).id, pk_value, force_unicode(new_object), CHANGE, change_message) |
|---|
| | 446 | return change_message or _('No fields changed.') |
|---|
| | 447 | |
|---|
| | 448 | def message_user(self, request, message): |
|---|
| | 449 | """ |
|---|
| | 450 | Send a message to the user. The default implementation |
|---|
| | 451 | posts a message using the auth Message object. |
|---|
| | 452 | """ |
|---|
| | 453 | request.user.message_set.create(message=message) |
|---|
| | 454 | |
|---|
| | 455 | def save_add(self, request, form, formsets, post_url_continue): |
|---|
| | 456 | """ |
|---|
| | 457 | Saves the object in the "add" stage and returns an HttpResponseRedirect. |
|---|
| | 458 | |
|---|
| | 459 | `form` is a bound Form instance that's verified to be valid. |
|---|
| | 460 | """ |
|---|
| | 461 | opts = self.model._meta |
|---|
| | 462 | new_object = form.save(commit=True) |
|---|
| | 463 | |
|---|
| | 464 | if formsets: |
|---|
| | 465 | for formset in formsets: |
|---|
| | 466 | # HACK: it seems like the parent obejct should be passed into |
|---|
| | 467 | # a method of something, not just set as an attribute |
|---|
| | 468 | formset.instance = new_object |
|---|
| | 469 | formset.save() |
|---|
| | 470 | |
|---|
| | 471 | pk_value = new_object._get_pk_val() |
|---|
| | 472 | self.log_addition(request, new_object) |
|---|
| | 473 | |
|---|
| | 474 | msg = _('The %(name)s "%(obj)s" was added successfully.') % {'name': force_unicode(opts.verbose_name), 'obj': force_unicode(new_object)} |
|---|
| | 475 | # Here, we distinguish between different save types by checking for |
|---|
| | 476 | # the presence of keys in request.POST. |
|---|
| | 477 | if request.POST.has_key("_continue"): |
|---|
| | 478 | self.message_user(request, msg + ' ' + _("You may edit it again below.")) |
|---|
| | 479 | if request.POST.has_key("_popup"): |
|---|
| | 480 | post_url_continue += "?_popup=1" |
|---|
| | 481 | return HttpResponseRedirect(post_url_continue % pk_value) |
|---|
| | 482 | |
|---|
| | 483 | if request.POST.has_key("_popup"): |
|---|
| | 484 | return HttpResponse('<script type="text/javascript">opener.dismissAddAnotherPopup(window, "%s", "%s");</script>' % \ |
|---|
| | 485 | # escape() calls force_unicode. |
|---|
| | 486 | (escape(pk_value), escape(new_object))) |
|---|
| | 487 | elif request.POST.has_key("_addanother"): |
|---|
| | 488 | self.message_user(request, msg + ' ' + (_("You may add another %s below.") % force_unicode(opts.verbose_name))) |
|---|
| | 489 | return HttpResponseRedirect(request.path) |
|---|
| | 490 | else: |
|---|
| | 491 | self.message_user(request, msg) |
|---|
| | 492 | |
|---|
| | 493 | # Figure out where to redirect. If the user has change permission, |
|---|
| | 494 | # redirect to the change-list page for this object. Otherwise, |
|---|
| | 495 | # redirect to the admin index. |
|---|
| | 496 | if self.has_change_permission(request, None): |
|---|
| | 497 | post_url = '../' |
|---|
| | 498 | else: |
|---|
| | 499 | post_url = '../../../' |
|---|
| | 500 | return HttpResponseRedirect(post_url) |
|---|
| | 501 | save_add = transaction.commit_on_success(save_add) |
|---|
| | 502 | |
|---|
| | 503 | def save_change(self, request, form, formsets=None): |
|---|
| | 504 | """ |
|---|
| | 505 | Saves the object in the "change" stage and returns an HttpResponseRedirect. |
|---|
| | 506 | |
|---|
| | 507 | `form` is a bound Form instance that's verified to be valid. |
|---|
| | 508 | |
|---|
| | 509 | `formsets` is a sequence of InlineFormSet instances that are verified to be valid. |
|---|
| | 510 | """ |
|---|
| | 511 | opts = self.model._meta |
|---|
| | 512 | new_object = form.save(commit=True) |
|---|
| | 513 | pk_value = new_object._get_pk_val() |
|---|
| | 514 | |
|---|
| | 515 | if formsets: |
|---|
| | 516 | for formset in formsets: |
|---|
| | 517 | formset.save() |
|---|
| | 518 | |
|---|
| | 519 | change_message = self.construct_change_message(request, form, formsets) |
|---|
| | 520 | self.log_change(request, new_object, change_message) |
|---|