Fixed #5780 -- Adjusted the ModelAdmin API to allow the created/updated objects
to be passed to the formsets prior to validation. This is a backward incompatible change for anyone overridding save_add or save_change. They have been removed in favor of more granular methods introduced in [8266] and the new response_add and response_change nethods. save_model has been renamed to save_form due to its slightly changed behavior. git-svn-id: http://code.djangoproject.com/svn/django/trunk@8273 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
50e6928c5b
commit
65be56816f
|
@ -452,102 +452,18 @@ class ModelAdmin(BaseModelAdmin):
|
||||||
"""
|
"""
|
||||||
request.user.message_set.create(message=message)
|
request.user.message_set.create(message=message)
|
||||||
|
|
||||||
def save_model(self, request, form, change):
|
def save_form(self, request, form, change):
|
||||||
"""
|
"""
|
||||||
Save and return a model given a ModelForm. ``change`` is True if the
|
Given a ModelForm return an unsaved instance. ``change`` is True if
|
||||||
object is being changed, and False if it's being added.
|
the object is being changed, and False if it's being added.
|
||||||
"""
|
"""
|
||||||
return form.save(commit=True)
|
return form.save(commit=False)
|
||||||
|
|
||||||
def save_formset(self, request, form, formset, change):
|
def save_formset(self, request, form, formset, change):
|
||||||
"""
|
"""
|
||||||
Save an inline formset attached to the object.
|
Given an inline formset return unsaved instances.
|
||||||
"""
|
"""
|
||||||
formset.save()
|
return formset.save(commit=False)
|
||||||
|
|
||||||
def save_add(self, request, form, formsets, post_url_continue):
|
|
||||||
"""
|
|
||||||
Saves the object in the "add" stage and returns an HttpResponseRedirect.
|
|
||||||
|
|
||||||
`form` is a bound Form instance that's verified to be valid.
|
|
||||||
"""
|
|
||||||
opts = self.model._meta
|
|
||||||
|
|
||||||
new_object = self.save_model(request, form, change=False)
|
|
||||||
if formsets:
|
|
||||||
for formset in formsets:
|
|
||||||
formset.instance = new_object
|
|
||||||
self.save_formset(request, form, formset, change=False)
|
|
||||||
|
|
||||||
pk_value = new_object._get_pk_val()
|
|
||||||
self.log_addition(request, new_object)
|
|
||||||
|
|
||||||
msg = _('The %(name)s "%(obj)s" was added successfully.') % {'name': force_unicode(opts.verbose_name), 'obj': force_unicode(new_object)}
|
|
||||||
# Here, we distinguish between different save types by checking for
|
|
||||||
# the presence of keys in request.POST.
|
|
||||||
if request.POST.has_key("_continue"):
|
|
||||||
self.message_user(request, msg + ' ' + _("You may edit it again below."))
|
|
||||||
if request.POST.has_key("_popup"):
|
|
||||||
post_url_continue += "?_popup=1"
|
|
||||||
return HttpResponseRedirect(post_url_continue % pk_value)
|
|
||||||
|
|
||||||
if request.POST.has_key("_popup"):
|
|
||||||
return HttpResponse('<script type="text/javascript">opener.dismissAddAnotherPopup(window, "%s", "%s");</script>' % \
|
|
||||||
# escape() calls force_unicode.
|
|
||||||
(escape(pk_value), escape(new_object)))
|
|
||||||
elif request.POST.has_key("_addanother"):
|
|
||||||
self.message_user(request, msg + ' ' + (_("You may add another %s below.") % force_unicode(opts.verbose_name)))
|
|
||||||
return HttpResponseRedirect(request.path)
|
|
||||||
else:
|
|
||||||
self.message_user(request, msg)
|
|
||||||
|
|
||||||
# Figure out where to redirect. If the user has change permission,
|
|
||||||
# redirect to the change-list page for this object. Otherwise,
|
|
||||||
# redirect to the admin index.
|
|
||||||
if self.has_change_permission(request, None):
|
|
||||||
post_url = '../'
|
|
||||||
else:
|
|
||||||
post_url = '../../../'
|
|
||||||
return HttpResponseRedirect(post_url)
|
|
||||||
save_add = transaction.commit_on_success(save_add)
|
|
||||||
|
|
||||||
def save_change(self, request, form, formsets=None):
|
|
||||||
"""
|
|
||||||
Saves the object in the "change" stage and returns an HttpResponseRedirect.
|
|
||||||
|
|
||||||
`form` is a bound Form instance that's verified to be valid.
|
|
||||||
|
|
||||||
`formsets` is a sequence of InlineFormSet instances that are verified to be valid.
|
|
||||||
"""
|
|
||||||
opts = self.model._meta
|
|
||||||
new_object = self.save_model(request, form, change=True)
|
|
||||||
pk_value = new_object._get_pk_val()
|
|
||||||
|
|
||||||
if formsets:
|
|
||||||
for formset in formsets:
|
|
||||||
self.save_formset(request, form, formset, change=True)
|
|
||||||
|
|
||||||
change_message = self.construct_change_message(request, form, formsets)
|
|
||||||
self.log_change(request, new_object, change_message)
|
|
||||||
|
|
||||||
msg = _('The %(name)s "%(obj)s" was changed successfully.') % {'name': force_unicode(opts.verbose_name), 'obj': force_unicode(new_object)}
|
|
||||||
if request.POST.has_key("_continue"):
|
|
||||||
self.message_user(request, msg + ' ' + _("You may edit it again below."))
|
|
||||||
if request.REQUEST.has_key('_popup'):
|
|
||||||
return HttpResponseRedirect(request.path + "?_popup=1")
|
|
||||||
else:
|
|
||||||
return HttpResponseRedirect(request.path)
|
|
||||||
elif request.POST.has_key("_saveasnew"):
|
|
||||||
msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % {'name': force_unicode(opts.verbose_name), 'obj': new_object}
|
|
||||||
self.message_user(request, msg)
|
|
||||||
return HttpResponseRedirect("../%s/" % pk_value)
|
|
||||||
elif request.POST.has_key("_addanother"):
|
|
||||||
self.message_user(request, msg + ' ' + (_("You may add another %s below.") % force_unicode(opts.verbose_name)))
|
|
||||||
return HttpResponseRedirect("../add/")
|
|
||||||
else:
|
|
||||||
self.message_user(request, msg)
|
|
||||||
return HttpResponseRedirect("../")
|
|
||||||
save_change = transaction.commit_on_success(save_change)
|
|
||||||
|
|
||||||
def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
|
def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
|
||||||
opts = self.model._meta
|
opts = self.model._meta
|
||||||
|
@ -574,6 +490,66 @@ class ModelAdmin(BaseModelAdmin):
|
||||||
"admin/%s/change_form.html" % app_label,
|
"admin/%s/change_form.html" % app_label,
|
||||||
"admin/change_form.html"
|
"admin/change_form.html"
|
||||||
], context, context_instance=template.RequestContext(request))
|
], context, context_instance=template.RequestContext(request))
|
||||||
|
|
||||||
|
def response_add(self, request, obj, post_url_continue='../%s/'):
|
||||||
|
"""
|
||||||
|
Determines the HttpResponse for the add_view stage.
|
||||||
|
"""
|
||||||
|
opts = obj._meta
|
||||||
|
pk_value = obj._get_pk_val()
|
||||||
|
|
||||||
|
msg = _('The %(name)s "%(obj)s" was added successfully.') % {'name': force_unicode(opts.verbose_name), 'obj': force_unicode(obj)}
|
||||||
|
# Here, we distinguish between different save types by checking for
|
||||||
|
# the presence of keys in request.POST.
|
||||||
|
if request.POST.has_key("_continue"):
|
||||||
|
self.message_user(request, msg + ' ' + _("You may edit it again below."))
|
||||||
|
if request.POST.has_key("_popup"):
|
||||||
|
post_url_continue += "?_popup=1"
|
||||||
|
return HttpResponseRedirect(post_url_continue % pk_value)
|
||||||
|
|
||||||
|
if request.POST.has_key("_popup"):
|
||||||
|
return HttpResponse('<script type="text/javascript">opener.dismissAddAnotherPopup(window, "%s", "%s");</script>' % \
|
||||||
|
# escape() calls force_unicode.
|
||||||
|
(escape(pk_value), escape(obj)))
|
||||||
|
elif request.POST.has_key("_addanother"):
|
||||||
|
self.message_user(request, msg + ' ' + (_("You may add another %s below.") % force_unicode(opts.verbose_name)))
|
||||||
|
return HttpResponseRedirect(request.path)
|
||||||
|
else:
|
||||||
|
self.message_user(request, msg)
|
||||||
|
|
||||||
|
# Figure out where to redirect. If the user has change permission,
|
||||||
|
# redirect to the change-list page for this object. Otherwise,
|
||||||
|
# redirect to the admin index.
|
||||||
|
if self.has_change_permission(request, None):
|
||||||
|
post_url = '../'
|
||||||
|
else:
|
||||||
|
post_url = '../../../'
|
||||||
|
return HttpResponseRedirect(post_url)
|
||||||
|
|
||||||
|
def response_change(self, request, obj):
|
||||||
|
"""
|
||||||
|
Determines the HttpResponse for the change_view stage.
|
||||||
|
"""
|
||||||
|
opts = obj._meta
|
||||||
|
pk_value = obj._get_pk_val()
|
||||||
|
|
||||||
|
msg = _('The %(name)s "%(obj)s" was changed successfully.') % {'name': force_unicode(opts.verbose_name), 'obj': force_unicode(obj)}
|
||||||
|
if request.POST.has_key("_continue"):
|
||||||
|
self.message_user(request, msg + ' ' + _("You may edit it again below."))
|
||||||
|
if request.REQUEST.has_key('_popup'):
|
||||||
|
return HttpResponseRedirect(request.path + "?_popup=1")
|
||||||
|
else:
|
||||||
|
return HttpResponseRedirect(request.path)
|
||||||
|
elif request.POST.has_key("_saveasnew"):
|
||||||
|
msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % {'name': force_unicode(opts.verbose_name), 'obj': obj}
|
||||||
|
self.message_user(request, msg)
|
||||||
|
return HttpResponseRedirect("../%s/" % pk_value)
|
||||||
|
elif request.POST.has_key("_addanother"):
|
||||||
|
self.message_user(request, msg + ' ' + (_("You may add another %s below.") % force_unicode(opts.verbose_name)))
|
||||||
|
return HttpResponseRedirect("../add/")
|
||||||
|
else:
|
||||||
|
self.message_user(request, msg)
|
||||||
|
return HttpResponseRedirect("../")
|
||||||
|
|
||||||
def add_view(self, request, form_url='', extra_context=None):
|
def add_view(self, request, form_url='', extra_context=None):
|
||||||
"The 'add' admin view for this model."
|
"The 'add' admin view for this model."
|
||||||
|
@ -592,29 +568,44 @@ class ModelAdmin(BaseModelAdmin):
|
||||||
post_url = '../../../'
|
post_url = '../../../'
|
||||||
|
|
||||||
ModelForm = self.get_form(request)
|
ModelForm = self.get_form(request)
|
||||||
inline_formsets = []
|
formsets = []
|
||||||
obj = self.model()
|
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
form = ModelForm(request.POST, request.FILES)
|
form = ModelForm(request.POST, request.FILES)
|
||||||
|
if form.is_valid():
|
||||||
|
form_validated = True
|
||||||
|
new_object = self.save_form(request, form, change=False)
|
||||||
|
else:
|
||||||
|
form_validated = False
|
||||||
|
new_object = self.model()
|
||||||
for FormSet in self.get_formsets(request):
|
for FormSet in self.get_formsets(request):
|
||||||
inline_formset = FormSet(data=request.POST, files=request.FILES,
|
formset = FormSet(data=request.POST, files=request.FILES,
|
||||||
instance=obj, save_as_new=request.POST.has_key("_saveasnew"))
|
instance=new_object,
|
||||||
inline_formsets.append(inline_formset)
|
save_as_new=request.POST.has_key("_saveasnew"))
|
||||||
if all_valid(inline_formsets) and form.is_valid():
|
formsets.append(formset)
|
||||||
return self.save_add(request, form, inline_formsets, '../%s/')
|
if all_valid(formsets) and form_validated:
|
||||||
|
new_object.save()
|
||||||
|
form.save_m2m()
|
||||||
|
for formset in formsets:
|
||||||
|
instances = self.save_formset(request, form, formset, change=False)
|
||||||
|
for instance in instances:
|
||||||
|
instance.save()
|
||||||
|
formset.save_m2m()
|
||||||
|
|
||||||
|
self.log_addition(request, new_object)
|
||||||
|
return self.response_add(request, new_object)
|
||||||
else:
|
else:
|
||||||
form = ModelForm(initial=dict(request.GET.items()))
|
form = ModelForm(initial=dict(request.GET.items()))
|
||||||
for FormSet in self.get_formsets(request):
|
for FormSet in self.get_formsets(request):
|
||||||
inline_formset = FormSet(instance=obj)
|
formset = FormSet(instance=self.model())
|
||||||
inline_formsets.append(inline_formset)
|
formsets.append(formset)
|
||||||
|
|
||||||
adminForm = AdminForm(form, list(self.get_fieldsets(request)), self.prepopulated_fields)
|
adminForm = AdminForm(form, list(self.get_fieldsets(request)), self.prepopulated_fields)
|
||||||
media = self.media + adminForm.media
|
media = self.media + adminForm.media
|
||||||
for fs in inline_formsets:
|
for formset in formsets:
|
||||||
media = media + fs.media
|
media = media + formset.media
|
||||||
|
|
||||||
inline_admin_formsets = []
|
inline_admin_formsets = []
|
||||||
for inline, formset in zip(self.inline_instances, inline_formsets):
|
for inline, formset in zip(self.inline_instances, formsets):
|
||||||
fieldsets = list(inline.get_fieldsets(request))
|
fieldsets = list(inline.get_fieldsets(request))
|
||||||
inline_admin_formset = InlineAdminFormSet(inline, formset, fieldsets)
|
inline_admin_formset = InlineAdminFormSet(inline, formset, fieldsets)
|
||||||
inline_admin_formsets.append(inline_admin_formset)
|
inline_admin_formsets.append(inline_admin_formset)
|
||||||
|
@ -626,11 +617,12 @@ class ModelAdmin(BaseModelAdmin):
|
||||||
'show_delete': False,
|
'show_delete': False,
|
||||||
'media': mark_safe(media),
|
'media': mark_safe(media),
|
||||||
'inline_admin_formsets': inline_admin_formsets,
|
'inline_admin_formsets': inline_admin_formsets,
|
||||||
'errors': AdminErrorList(form, inline_formsets),
|
'errors': AdminErrorList(form, formsets),
|
||||||
'root_path': self.admin_site.root_path,
|
'root_path': self.admin_site.root_path,
|
||||||
}
|
}
|
||||||
context.update(extra_context or {})
|
context.update(extra_context or {})
|
||||||
return self.render_change_form(request, context, add=True)
|
return self.render_change_form(request, context, add=True)
|
||||||
|
add_view = transaction.commit_on_success(add_view)
|
||||||
|
|
||||||
def change_view(self, request, object_id, extra_context=None):
|
def change_view(self, request, object_id, extra_context=None):
|
||||||
"The 'change' admin view for this model."
|
"The 'change' admin view for this model."
|
||||||
|
@ -656,26 +648,43 @@ class ModelAdmin(BaseModelAdmin):
|
||||||
return self.add_view(request, form_url='../../add/')
|
return self.add_view(request, form_url='../../add/')
|
||||||
|
|
||||||
ModelForm = self.get_form(request, obj)
|
ModelForm = self.get_form(request, obj)
|
||||||
inline_formsets = []
|
formsets = []
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
form = ModelForm(request.POST, request.FILES, instance=obj)
|
form = ModelForm(request.POST, request.FILES, instance=obj)
|
||||||
for FormSet in self.get_formsets(request, obj):
|
if form.is_valid():
|
||||||
inline_formset = FormSet(request.POST, request.FILES, instance=obj)
|
form_validated = True
|
||||||
inline_formsets.append(inline_formset)
|
new_object = self.save_form(request, form, change=True)
|
||||||
|
else:
|
||||||
|
form_validated = False
|
||||||
|
new_object = obj
|
||||||
|
for FormSet in self.get_formsets(request, new_object):
|
||||||
|
formset = FormSet(request.POST, request.FILES,
|
||||||
|
instance=new_object)
|
||||||
|
formsets.append(formset)
|
||||||
|
|
||||||
if all_valid(inline_formsets) and form.is_valid():
|
if all_valid(formsets) and form_validated:
|
||||||
return self.save_change(request, form, inline_formsets)
|
new_object.save()
|
||||||
|
form.save_m2m()
|
||||||
|
for formset in formsets:
|
||||||
|
instances = self.save_formset(request, form, formset, change=True)
|
||||||
|
for instance in instances:
|
||||||
|
instance.save()
|
||||||
|
formset.save_m2m()
|
||||||
|
|
||||||
|
change_message = self.construct_change_message(request, form, formsets)
|
||||||
|
self.log_change(request, new_object, change_message)
|
||||||
|
return self.response_change(request, new_object)
|
||||||
else:
|
else:
|
||||||
form = ModelForm(instance=obj)
|
form = ModelForm(instance=obj)
|
||||||
for FormSet in self.get_formsets(request, obj):
|
for FormSet in self.get_formsets(request, obj):
|
||||||
inline_formset = FormSet(instance=obj)
|
formset = FormSet(instance=obj)
|
||||||
inline_formsets.append(inline_formset)
|
formsets.append(formset)
|
||||||
|
|
||||||
adminForm = AdminForm(form, self.get_fieldsets(request, obj), self.prepopulated_fields)
|
adminForm = AdminForm(form, self.get_fieldsets(request, obj), self.prepopulated_fields)
|
||||||
media = self.media + adminForm.media
|
media = self.media + adminForm.media
|
||||||
|
|
||||||
inline_admin_formsets = []
|
inline_admin_formsets = []
|
||||||
for inline, formset in zip(self.inline_instances, inline_formsets):
|
for inline, formset in zip(self.inline_instances, formsets):
|
||||||
fieldsets = list(inline.get_fieldsets(request, obj))
|
fieldsets = list(inline.get_fieldsets(request, obj))
|
||||||
inline_admin_formset = InlineAdminFormSet(inline, formset, fieldsets)
|
inline_admin_formset = InlineAdminFormSet(inline, formset, fieldsets)
|
||||||
inline_admin_formsets.append(inline_admin_formset)
|
inline_admin_formsets.append(inline_admin_formset)
|
||||||
|
@ -689,11 +698,12 @@ class ModelAdmin(BaseModelAdmin):
|
||||||
'is_popup': request.REQUEST.has_key('_popup'),
|
'is_popup': request.REQUEST.has_key('_popup'),
|
||||||
'media': mark_safe(media),
|
'media': mark_safe(media),
|
||||||
'inline_admin_formsets': inline_admin_formsets,
|
'inline_admin_formsets': inline_admin_formsets,
|
||||||
'errors': AdminErrorList(form, inline_formsets),
|
'errors': AdminErrorList(form, formsets),
|
||||||
'root_path': self.admin_site.root_path,
|
'root_path': self.admin_site.root_path,
|
||||||
}
|
}
|
||||||
context.update(extra_context or {})
|
context.update(extra_context or {})
|
||||||
return self.render_change_form(request, context, change=True, obj=obj)
|
return self.render_change_form(request, context, change=True, obj=obj)
|
||||||
|
change_view = transaction.commit_on_success(change_view)
|
||||||
|
|
||||||
def changelist_view(self, request, extra_context=None):
|
def changelist_view(self, request, extra_context=None):
|
||||||
"The 'change list' admin view for this model."
|
"The 'change list' admin view for this model."
|
||||||
|
|
|
@ -521,6 +521,44 @@ with an operator:
|
||||||
Performs a full-text match. This is like the default search method but uses
|
Performs a full-text match. This is like the default search method but uses
|
||||||
an index. Currently this is only available for MySQL.
|
an index. Currently this is only available for MySQL.
|
||||||
|
|
||||||
|
``ModelAdmin`` methods
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
``save_form(self, request, form, change)``
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The ``save_form`` method is given the ``HttpRequest``, a ``ModelForm``
|
||||||
|
instance and a boolean value based on whether it is adding or changing the
|
||||||
|
object.
|
||||||
|
|
||||||
|
This method should return an unsaved instance. For example to attach
|
||||||
|
``request.user`` to the object prior to saving::
|
||||||
|
|
||||||
|
class ArticleAdmin(admin.ModelAdmin):
|
||||||
|
def save_form(self, request, form, change):
|
||||||
|
instance = form.save(commit=False)
|
||||||
|
instance.user = request.user
|
||||||
|
return instance
|
||||||
|
|
||||||
|
``save_formset(self, request, form, formset, change)``
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The ``save_formset`` method is given the ``HttpRequest``, the parent
|
||||||
|
``ModelForm`` instance and a boolean value baesed on whether it is adding or
|
||||||
|
changing the parent object.
|
||||||
|
|
||||||
|
This method should return unsaved instances. These instances will later be
|
||||||
|
saved to the database. By default the formset will only return instances that
|
||||||
|
have changed. For example to attach ``request.user`` to each changed formset
|
||||||
|
model instance::
|
||||||
|
|
||||||
|
class ArticleAdmin(admin.ModelAdmin):
|
||||||
|
def save_formset(self, request, form, formset, change):
|
||||||
|
instances = formset.save(commit=False)
|
||||||
|
for instance in instances:
|
||||||
|
instance.user = request.user
|
||||||
|
return instances
|
||||||
|
|
||||||
``ModelAdmin`` media definitions
|
``ModelAdmin`` media definitions
|
||||||
--------------------------------
|
--------------------------------
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,9 @@ class Article(models.Model):
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return self.title
|
return self.title
|
||||||
|
|
||||||
|
class ArticleInline(admin.TabularInline):
|
||||||
|
model = Article
|
||||||
|
|
||||||
class ArticleAdmin(admin.ModelAdmin):
|
class ArticleAdmin(admin.ModelAdmin):
|
||||||
list_display = ('content', 'date')
|
list_display = ('content', 'date')
|
||||||
list_filter = ('date',)
|
list_filter = ('date',)
|
||||||
|
@ -61,5 +64,5 @@ class ModelWithStringPrimaryKey(models.Model):
|
||||||
|
|
||||||
admin.site.register(Article, ArticleAdmin)
|
admin.site.register(Article, ArticleAdmin)
|
||||||
admin.site.register(CustomArticle, CustomArticleAdmin)
|
admin.site.register(CustomArticle, CustomArticleAdmin)
|
||||||
admin.site.register(Section)
|
admin.site.register(Section, inlines=[ArticleInline])
|
||||||
admin.site.register(ModelWithStringPrimaryKey)
|
admin.site.register(ModelWithStringPrimaryKey)
|
||||||
|
|
|
@ -11,10 +11,90 @@ from django.utils.html import escape
|
||||||
# local test models
|
# local test models
|
||||||
from models import Article, CustomArticle, Section, ModelWithStringPrimaryKey
|
from models import Article, CustomArticle, Section, ModelWithStringPrimaryKey
|
||||||
|
|
||||||
|
class AdminViewBasicTest(TestCase):
|
||||||
|
fixtures = ['admin-views-users.xml']
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.client.login(username='super', password='secret')
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
self.client.logout()
|
||||||
|
|
||||||
|
def testTrailingSlashRequired(self):
|
||||||
|
"""
|
||||||
|
If you leave off the trailing slash, app should redirect and add it.
|
||||||
|
"""
|
||||||
|
request = self.client.get('/test_admin/admin/admin_views/article/add')
|
||||||
|
self.assertRedirects(request,
|
||||||
|
'/test_admin/admin/admin_views/article/add/'
|
||||||
|
)
|
||||||
|
|
||||||
|
def testBasicAddGet(self):
|
||||||
|
"""
|
||||||
|
A smoke test to ensure GET on the add_view works.
|
||||||
|
"""
|
||||||
|
response = self.client.get('/test_admin/admin/admin_views/section/add/')
|
||||||
|
self.failUnlessEqual(response.status_code, 200)
|
||||||
|
|
||||||
|
def testBasicEditGet(self):
|
||||||
|
"""
|
||||||
|
A smoke test to ensureGET on the change_view works.
|
||||||
|
"""
|
||||||
|
response = self.client.get('/test_admin/admin/admin_views/section/1/')
|
||||||
|
self.failUnlessEqual(response.status_code, 200)
|
||||||
|
|
||||||
|
def testBasicAddPost(self):
|
||||||
|
"""
|
||||||
|
A smoke test to ensure POST on add_view works.
|
||||||
|
"""
|
||||||
|
post_data = {
|
||||||
|
"name": u"Another Section",
|
||||||
|
# inline data
|
||||||
|
"article_set-TOTAL_FORMS": u"3",
|
||||||
|
"article_set-INITIAL_FORMS": u"0",
|
||||||
|
}
|
||||||
|
response = self.client.post('/test_admin/admin/admin_views/section/add/', post_data)
|
||||||
|
self.failUnlessEqual(response.status_code, 302) # redirect somewhere
|
||||||
|
|
||||||
|
def testBasicEditPost(self):
|
||||||
|
"""
|
||||||
|
A smoke test to ensure POST on edit_view works.
|
||||||
|
"""
|
||||||
|
post_data = {
|
||||||
|
"name": u"Test section",
|
||||||
|
# inline data
|
||||||
|
"article_set-TOTAL_FORMS": u"4",
|
||||||
|
"article_set-INITIAL_FORMS": u"1",
|
||||||
|
"article_set-0-id": u"1",
|
||||||
|
# there is no title in database, give one here or formset
|
||||||
|
# will fail.
|
||||||
|
"article_set-0-title": u"Need a title.",
|
||||||
|
"article_set-0-content": u"<p>test content</p>",
|
||||||
|
"article_set-0-date_0": u"2008-03-18",
|
||||||
|
"article_set-0-date_1": u"11:54:58",
|
||||||
|
"article_set-1-id": u"",
|
||||||
|
"article_set-1-title": u"",
|
||||||
|
"article_set-1-content": u"",
|
||||||
|
"article_set-1-date_0": u"",
|
||||||
|
"article_set-1-date_1": u"",
|
||||||
|
"article_set-2-id": u"",
|
||||||
|
"article_set-2-title": u"",
|
||||||
|
"article_set-2-content": u"",
|
||||||
|
"article_set-2-date_0": u"",
|
||||||
|
"article_set-2-date_1": u"",
|
||||||
|
"article_set-3-id": u"",
|
||||||
|
"article_set-3-title": u"",
|
||||||
|
"article_set-3-content": u"",
|
||||||
|
"article_set-3-date_0": u"",
|
||||||
|
"article_set-3-date_1": u"",
|
||||||
|
}
|
||||||
|
response = self.client.post('/test_admin/admin/admin_views/section/1/', post_data)
|
||||||
|
self.failUnlessEqual(response.status_code, 302) # redirect somewhere
|
||||||
|
|
||||||
def get_perm(Model, perm):
|
def get_perm(Model, perm):
|
||||||
"""Return the permission object, for the Model"""
|
"""Return the permission object, for the Model"""
|
||||||
ct = ContentType.objects.get_for_model(Model)
|
ct = ContentType.objects.get_for_model(Model)
|
||||||
return Permission.objects.get(content_type=ct,codename=perm)
|
return Permission.objects.get(content_type=ct, codename=perm)
|
||||||
|
|
||||||
class AdminViewPermissionsTest(TestCase):
|
class AdminViewPermissionsTest(TestCase):
|
||||||
"""Tests for Admin Views Permissions."""
|
"""Tests for Admin Views Permissions."""
|
||||||
|
@ -77,19 +157,6 @@ class AdminViewPermissionsTest(TestCase):
|
||||||
'username': 'joepublic',
|
'username': 'joepublic',
|
||||||
'password': 'secret'}
|
'password': 'secret'}
|
||||||
|
|
||||||
def testTrailingSlashRequired(self):
|
|
||||||
"""
|
|
||||||
If you leave off the trailing slash, app should redirect and add it.
|
|
||||||
"""
|
|
||||||
self.client.post('/test_admin/admin/', self.super_login)
|
|
||||||
|
|
||||||
request = self.client.get(
|
|
||||||
'/test_admin/admin/admin_views/article/add'
|
|
||||||
)
|
|
||||||
self.assertRedirects(request,
|
|
||||||
'/test_admin/admin/admin_views/article/add/'
|
|
||||||
)
|
|
||||||
|
|
||||||
def testLogin(self):
|
def testLogin(self):
|
||||||
"""
|
"""
|
||||||
Make sure only staff members can log in.
|
Make sure only staff members can log in.
|
||||||
|
|
Loading…
Reference in New Issue