Steve
Steve

Reputation: 49

How do I access form fields in a template in Django?

I am using a model-based form to create a form based off a data model. The insert part works fine, but I am now trying to do the "edit" page. my problem is I need the ID/primary key of the original model for the post action and documentation (and a previous thread here) seems to have told me to try both form.id and form.instance.id, but neither seem to work. Any ideas or help is appreciated!

Here's my template:

<form action="/athlete/edit/{{ form.mod_athlete.id }}" method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit" />
</form>

Here's part of my View:

def changeathlete(request, athlete_id):
        if request.method == 'POST': # If the form has been submitted...
                form = AthleteForm(request.POST) # A form bound to the POST data
                if form.is_valid(): # All validation rules pass
                        form.save()
                        return HttpResponse("Athlete changed!") # Redirect after POST
        else:
                mod_athlete = Athlete.objects.get(pk=athlete_id)
                form = AthleteForm(instance=mod_athlete) # An unbound form

        return render_to_response('edit.html', {
                'form': form,
        }, context_instance=RequestContext(request))

Any help is appreciated and if you need more info, I'll be happy to provide it. I, of course, am new to Django and real programming so I'm just building off the tutorial and this to learn. Thanks!

Update

relevant parts of urls.py:

url(r'^$', 'rosters.views.index', name='index'),
url(r'^admin/', include(admin.site.urls)),
url(r'^athlete/add/', 'rosters.views.createathlete'),
url(r'^athlete/edit/(?P<athlete_id>\d+)/', 'rosters.views.changeathlete'),
url(r'^meet/(?P<meet_slug>\w+)/', 'rosters.views.meetindex'),
url(r'^meet/(?P<meet_slug>\w+)/(?P<occurence_name>\w+)/', 'rosters.views.occurenceindex'),
url(r'^meet/(?P<meet_slug>\w+)/(?P<occurence_name>\w+)/events/', 'rosters.views.meetevents'),
url(r'^meet/(?P<meet_slug>\w+)/(?P<occurence_name>\w+)/events/(?P<event_id>\w+)/', 'rosters.views.addathletes'),

Upvotes: 0

Views: 2171

Answers (3)

Thierry Lam
Thierry Lam

Reputation: 46294

If you are staying on the same page during the edit process(for example http://localhost:8000/athlete/edit/1234/), you don't need to specify anything in the action attribute on your form, the following should work fine:

<form action="" method="post">{% csrf_token %}
  {{ form.as_p }}
  <input type="submit" value="Submit" />
</form>

Your form should also pass in the instance object in the POST case:

def changeathlete(request, athlete_id):
    mod_athlete = Athlete.objects.get(pk=athlete_id)
    if request.method == 'POST': # If the form has been submitted...
        form = AthleteForm(request.POST, instance=mod_athlete) # A form bound to the POST data
        if form.is_valid(): # All validation rules pass
            form.save()
            return HttpResponse("Athlete changed!") # Redirect after POST
    else:
        form = AthleteForm(instance=mod_athlete) # An unbound form

    return render_to_response('edit.html', {
            'form': form,
    }, context_instance=RequestContext(request))

Upvotes: 2

Sam Dolan
Sam Dolan

Reputation: 32542

The Athlete instance will be stored on the ModelForm, so you can do:

{{ form.instance.id }}

Also, you want to pass your Athlete instance in the POST case you you'll actually update the instance (rather than create a new one).

Upvotes: 3

j_syk
j_syk

Reputation: 6631

I checked it against some code I have for editing a form, your view seems to be fine. As geekam asked, what is you urls.py like? It should be something like

(r'^athlete/edit/(?P<athlete_id>\d+)/$', changeathlete),

edit: the regex I posted in the url capture assumes a numerical id- I don't know what your ids are

Upvotes: 0

Related Questions