Reputation: 63
I'm new to Django and Python, and have spent a couple days trying to solve this problem. I've tried several approaches in other threads here, but I think I'm missing some basic concept because none of them have worked for me. Here's what I'm trying to do:
I'm using ModelForm, and I have created a form for adding records that includes a foreign key. I want this value to be set by default to match the record that was displayed on the page I linked from. [Code shown below edited to show suggested corrections].
Here's the relevant code from views.py:
def add_sighting(request):
unit = request.GET.get('unit')
form = SightingForm(request.POST or None, initial={'unit':unit})
if form.is_valid():
sighting = form.save(commit=False)
sighting.save()
return redirect(index)
return render_to_response('trainapp/add_sighting_form.html',
{'unit': unit, 'sighting_form': form},
context_instance=RequestContext(request))
Here's the relevant code from add_sighting_form.html:
<form action="/trainapp/add_sighting/" method="post">
{% csrf_token %}
<table>
{{ sighting_form.as_table }}
</table>
<input type="submit" value="Save" />
</form>
Here's the relevant code from the template I linked from:
<p><a href="/trainapp/add_sighting/?unit={{ unit.id }}">Add sighting</a></p>
Upvotes: 6
Views: 3921
Reputation: 1213
Several approaches might work here.
The easiest one is using the initial parameter when creating an instance of the form before you pass it into the context of some view.
Say you are using a view method as follow:
def some_view( request ):
id = request.GET.get( 'record-id' )
# do check if id is valid...
# load some record
record = Record.objects.get( pk=id )
# create a form instance
form = RecordForm( initial={ 'some_key_field_name':record.id } )
# set up context
context = Context({
'record' : record,
'form' : form
})
# render the templateview using the above context
# and return a HttpResponse ...
If you are using class based views instead, you might override get_context_data to get a similar result.
Based on your code I also want to suggest you take a look at class based views in Django. The can handle getting and posting forms for you. It even takes care of creating the (default) form for you.
The equivalent of the posted code would be something like this:
class CreateSightingView( CreateView ):
model = Sighting
def get_context_data( self, **kwargs ):
# call the super to get the default context
data = super( CreateSightingView, self ).get_context_data( **kwargs )
# add the initial value here
# but first get the id from the request GET data
id = self.request.GET.get( 'record-id' )
# again: do some checking of id
data.get( 'form' ).initial[ 'unit' ] = id
return data
Upvotes: 4