HiveBrain v1.2.0
Get Started
← Back to all entries
snippetpythondjangoMinor

An idiom to use the same view function to create or edit an object?

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
editsamethecreateidiomfunctionviewobjectuse

Problem

Here is the skeleton of my (first!) Django app:

# models.py
class Task(models.Model):
    description = models.CharField(max_length = 200)
    ...

# forms.py
class AddTaskForm(forms.ModelForm):
    class Meta:
        model = Task


I then created two views using AddTaskForm: one to create a new instance, the other to edit an existing one. I was able to refactor those two views (and the function they call) into one, but I'm not sure I got the best possible result...

# urls.py:
(r'^yata/add_task/

And here is the corresponding part of the template:

# edit.html
{% if id %}
    
{% else %}
    
{% endif %}
{{ form.as_p }}


Is there a better Django idiom to handle this 'add or create' issue?
Or can this be considered a correct way?, 'yata.views.edit'), (r'^yata/(?P\d+)/edit/

And here is the corresponding part of the template:

%%CODEBLOCK_2%%

Is there a better Django idiom to handle this 'add or create' issue?
Or can this be considered a correct way?, 'yata.views.edit'), # views.py def edit(request, task_id = None): t = get_object_or_404(Task, pk=task_id) if task_id else None if request.method == 'POST': form = AddTaskForm(request.POST, instance=t) if form.is_valid(): form.save() return HttpResponseRedirect('/yata/') else: form = AddTaskForm(instance = t) # Either the form was not valid, or we've just created it d = {'form': form} if task_id: # The template needs the id to decide if the form's action # is .../add_task or .../{{id}}/edit d['id'] = t.id return render_to_response('yata/edit.html', d, context_instance=RequestContext(request))


And here is the corresponding part of the template:

%%CODEBLOCK_2%%

Is there a better Django idiom to handle this 'add or create' issue?
Or can this be considered a correct way?

Solution

I have looked at your code and I think that it actually looks pretty clean and straight forward. However, I would suggest that you make it more DRY by using reverse() to figure out what action to assign to the form.

views.py:

if task_id:
    action = reverse(edit, args=[task_id])
else:
    action = reverse(edit)
d['action'] = action


edit.html:


    {{ form.as_p }}
    

Code Snippets

if task_id:
    action = reverse(edit, args=[task_id])
else:
    action = reverse(edit)
d['action'] = action
<form action="{{ action }}" method="post">
    {{ form.as_p }}
    <input type="submit" value="Save!" />
</form>

Context

StackExchange Code Review Q#374, answer score: 2

Revisions (0)

No revisions yet.