Reputation: 1834
I have a model for which i'll have one single instance, so i need to override the changelist_view to by-pass it (only if i have at least one record saved), and jump directly to change_view. i found snippet online and it works well for it, so i wrote my custom changelist_view:
def changelist_view(self, request, extra_context=None):
queryset = self.model.objects.all()
if queryset.count()>0:
try:
obj = queryset[0]
return self.change_view(request, str(obj.id), extra_context)
except IndexError:
pass
return super(MyModelAdmin, self).changelist_view(request, extra_context)
this works until I try to save. The difference from the normal change_view is in the url. the normal has the object id:
http://127.0.0.1:8000/admin/myapp/mymodel/2
instead with modified version i have:
http://127.0.0.1:8000/admin/myapp/mymodel/
if i try to save i got this error:
You called this URL via POST, but the URL doesn't end
in a slash and you have APPEND_SLASH set. Django can't redirect to
the slash URL while maintaining POST data. Change your form to
point to 127.0.0.1:8000/admin/myapp1/mymodel/None/ (note
the trailing slash), or set APPEND_SLASH=False in your
Django settings.
At the moment the only trick that works for me is a HttpResponseRedirect(url), with as url the change_view url hardcoded with object id.
is there a more elegant way?
thanks Luke
Upvotes: 3
Views: 4867
Reputation: 21
When using
def changelist_view(self, request, extra_context=None):
django will insert an action="None" in the Html output which causes the above mentioned error when submitting the post. Instead try
def changelist_view(self, request, extra_context=""):
Upvotes: 0
Reputation: 37319
You can change target URL the admin will redirect to after processing your edits by using the response_change
method on your model admin. That receives the request and the changed object as parameters, and can return a redirect to a dynamically calculated URL.
def response_change(self, request, obj):
# call the parent version to collect messages for the user
original_response = super(MyModelAdmin, self).response_change(request, obj)
if "_popup" in request.POST:
return original_response
return HttpResponseRedirect(reverse("admin:myapp_mymodel_change", args=[obj.id]))
There's also a response_add
, but I doubt you'll need that if you're using a singleton model. Likewise, there are ways to test for whether the user selected "save and add another", "save and continue editing" or just "save" but you probably don't care about that distinction for a singleton.
Upvotes: 1