I have one large view function where a user can Add, Edit, Delete, and Update his education. I am currently doing this all in one view because I haven't yet learned how to split up views by function. Here is what I currently have --
I have a single URL pointing to the view --
url(r'^profile/edit/education/$', 'views.edit_education', name='edit_education')
Here is my model/modelform --
class Education(models.Model):
school = models.CharField(max_length=100)
class_year = models.IntegerField(max_length=4, blank=True, null=True, choices=YEAR)
degree = models.CharField(max_length=100, blank=True)
user = models.ForeignKey('UserProfile')
class EducationForm(ModelForm):
class Meta:
model = Education
exclude = ('user',)
Here is my view --
@login_required
def edit_education(request, edit=0):
"""
In the edit profile page, allows a user to edit his education
and add multiple school entries.
"""
profile = request.user.get_profile()
education = profile.education_set.order_by('-class_year') # for the template. display all eduation entries
# unindented for legibility
if request.method == 'POST':
if 'Add School' in request.POST.values():
form = EducationForm(data=request.POST, request=request) # passing request to form to do validation based on request.user
if form.is_valid():
new_education = form.save(commit=False)
new_education.user = profile
new_education.save()
return redirect('edit_education')
if 'Delete' in request.POST.values():
for education_id in [key[7:] for key, value in request.POST.iteritems() if key.startswith('delete')]:
Education.objects.get(id=education_id).delete()
return redirect('edit_education')
if 'Edit' in request.POST.values():
for education_id in [key[5:] for key, value in request.POST.iteritems() if value == 'Edit' and key.startswith('edit')]:
edit = 1
school_object = Education.objects.get(id = education_id)
form = EducationForm(instance = school_object, request=request)
return render_to_response('userprofile/edit_education.html', {'form': form, 'education':education, 'edit': edit, 'education_id': education_id}, context_instance=RequestContext(request))
if 'Cancel' in request.POST.values():
return redirect('edit_education')
if 'Save Changes' in request.POST.values():
form = EducationForm(request.POST, request=request, edit=1)
if form.is_valid():
Education.objects.get(id=request.POST['education_id']).delete() # is there a way to update instead of delete and re-add?
new_education = form.save(commit=False)
new_education.user = profile
new_education.save()
return redirect('edit_education')
else:
form = EducationForm(request=request)
return render_to_response('userprofile/edit_education.html', {'form': form, 'education': education, }, context_instance=RequestContext(request))
And finally, my template --
<h3>Edit education info for {{user.get_full_name}}</h3>
<form action="." method="post"> {% csrf_token %}
{% if education %}
{% for education in education %}
<p><b>{{ education.school }}</b> {% if education.class_year %}{{ education.class_year|shorten_year}}, {% endif %} {{ education.degree}}
<input type="submit" name="edit_{{education.id}}" value='Edit' />
<input type="submit" name="delete_{{education.id}}" value="Delete" /></p>
{% endfor %}
{% endif %}
<table>
<input type="hidden" name="education_id" value="{{education_id}}" />
<tr><td>School:</td><td>{{form.school}}{{form.school.errors}}</td></tr>
<tr><td>Class Year</td><td>{{form.class_year}}{{form.class_year.errors}}</td></tr>
<tr><td>Degree:</td><td>{{form.degree}}{{form.degree.errors}}</td></tr>
<tr>{{form.non_field_errors}}</tr>
</table>
{% if not edit %}
<p><input type="submit" name="add" value="Add School" ></p>
{% else %}
<p><input type="submit" name="save" value="Save Changes" >
<input type="submit" name="cancel" value="Cancel" ></p>
{% endif %}
</form>
And the end is here. How would I separate one of these actions in the view into separate view functions using separate URLs? One or two examples would be more than enough. Thank you very much for your help.