Karl
Karl

Reputation: 743

How to re-use a view to update objects in Django?

I am trying to get my head around Class based views (I'm new to Django). I currently have a project that uses function based views. My 'create' view renders a form and successfully submits to the database. However, I need an edit/update function so the obvious option is to re-use the 'create' function I made but I'm struggling to work it out and adhere to the DRY principle.

Is using Class based views the right way to go? Do they handle the creation of all the 'CRUD' views?

I'm currently working my way through the GoDjano tutorials on Class based views but its still not sinking in.

Any help/pointers would be, as usual, much appreciated.

Upvotes: 0

Views: 367

Answers (2)

knbk
knbk

Reputation: 53669

As you can see in the source code, a CreateView and an UpdateView are very similar. The only difference is that a CreateView sets self.object to None, forcing the creation of a new object, while UpdateView sets it to the updated object.

Creating a UpdateOrCreateView would be as simple as subclassing UpdateView and overriding the get_object method to return None, should a new object be created.

class UpdateOrCreateView(UpdateView):
    def get_object(self, queryset=None):
        # or any other condition
        if not self.kwargs.get('pk', None):
            return None
        return super(UpdateOrCreateView, self).get_object(queryset)

The GoDjango tutorials don't seem to be out of date (CBVs have barely changed since their introduction), but they do seem to be missing some of the essential views in their tutorials.

Upvotes: 1

Peter
Peter

Reputation: 1798

CBV is in my opinion never the solution. A dry FBV is (assuming you have created an imported a form RecordForm and a model Record, imported get_object_or_404 and redirect):

@render_to('sometemplate.html')
def update(request, pk=None):
    if pk:
        record = get_object_or_404(Record, pk=pk)
    else:
        record = None

    if request.POST:
        form = RecordForm(request.POST)

        if form.is_valid():
            form.save()
            return redirect('somepage')
        else:
            // ....
    elif record:
        form = RecordForm(instance=record)
    else:
        form = RecordForm()

    return { 'form': form, 'record': record }

I also integrate the messages framework to for example add an error message when form.is_valid() is False.

I use a render_to decorator but that's not necessary (but then you have to return the view results differently).

Upvotes: 0

Related Questions