Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Admin: Pre-populating values from POST or GET?

In my Django 1.2.4 site, I would like to direct the user to an admin page that is pre-filled out with some values, based on the current data they are working with. For example:

{% for person in people %}
    <tr>
        <td>{{person}}</td>
        <td><a href='admin/foo/bar/add?name={{person}}'>Create a foo for {{person}}</td>
    </tr>
{% endfor %}

Then, when the user clicks on the link, the name field is pre-populated with the value {{person}}.

Does the Django Admin interface support doing this? The Django admin forms use POST, but I'm not sure how to add POST data to a request from the template.

Or, I could set GET variables, then use custom JavaScript in the form to set values accordingly.

like image 833
Nick Heiner Avatar asked Feb 07 '11 18:02

Nick Heiner


1 Answers

According to the source code (and a quick test), Django does support the use of GET parameters as initial values for modelforms in the admin. It even supports many-to-many relations.

Did you try this? Maybe it's the missing slash at the end of the url.

admin/foo/bar/add?name=Foobar

Probably gets redirected to ...

admin/foo/bar/add/

... thus dropping the querystring. So try to add a slash there and see if it works.

admin/foo/bar/add/?name={{ person }}

Update (Prefilling boolean fields)

Just in case someone else is having problems with prefilling boolean fields:

If you pass any value at all in the querystring, e.g. admin/foo/bar/add/?is_active=foo, this will prefill the is_active field with True (since any non-empty string is a truthy value). Therefore, if you want to "uncheck" a checkbox for a given field, pass no value at all, like admin/foo/bar/add/?is_active=


This is a snippet of the code from the add_view method on ModelAdmin responsible for using GET parameters as initial values. http://code.djangoproject.com/browser/django/trunk/django/contrib/admin/options.py#L878

# Prepare the dict of initial data from the request.
# We have to special-case M2Ms as a list of comma-separated PKs.
initial = dict(request.GET.items())
for k in initial:
    try:
        f = opts.get_field(k)
    except models.FieldDoesNotExist:
        continue
    if isinstance(f, models.ManyToManyField):
        initial[k] = initial[k].split(",")

form = ModelForm(initial=initial)
like image 70
Reiner Gerecke Avatar answered Oct 17 '22 15:10

Reiner Gerecke