Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Update Form?

I have a form that users enter in information on locations. I'm trying to make an update form so users can click the update button on a location and the update form comes populated with the data thats already there for that location. I have followed the Django docs but I am getting a blank screen. I am unsure how to get it to reference which location to update. Here is what I have so far.

models.py

class Location(models.Model):
    # Details on location

views.py

    def locations(request):
        return render_to_response('locations/locations.html', {'locations': Location.objects.all() })

    def location(request, location_id=1):
        return render_to_response('locations/location.html', {'location': Location.objects.get(id=location_id) })

    def create(request):
        if request.POST:
            form = LocationForm(request.POST, request.FILES)
            if form.is_valid():
                form.save()

                return HttpResponseRedirect('/accounts/loggedin/locations/all/')
        else:
            form = LocationForm()

        args = {}
        args.update(csrf(request))

        args['form'] = form

        return render_to_response('locations/create_location.html', args)

def edit_location(request): 

    if request.POST:
        form = LocationUpdate(request.POST, request.FILES)
        if form.is_valid():
            form.save()

            return HttpResponseRedirect('/accounts/loggedin/locations/all/')
    else:
        form = LocationUpdate()

    args = {}
    args.update(csrf(request))

    args['form'] = form

    return render_to_response('locations/location_update.html', args) 

forms.py

from django.views.generic.edit import UpdateView
from models import Location

class LocationForm(forms.ModelForm):

    class Meta:
        model = Location
        exclude = ('timestamp', 'updated')

class LocationUpdate(UpdateView):
    model = Location
    template_name_suffix = '_update_form'

url.py

url(r'^accounts/loggedin/location/update/$', 'assessments.views.edit_location'),

location_update.html

<!DOCTYPE html>
    <html>
        <head>

        </head>
        <body>
        <form action="" method="post">{% csrf_token %}
        {{ form.as_p }}
        <input type="submit" value="update" />
    </form>
        </body>
    </html>

or should it go in location.html. If i add it in there i get a CSRF verification failed error

<div class="row">
        <div class="col-md-4">
            <dl class="dl-horizontal">
                <dt>ID:</dt>
                <dd>{{ location.id }}</dd>
                <br />
                <dt>Company:</dt>
                <dd>{{ location.company }}</dd>
                <dt>Address:</dt>
                <dd>{{ location.address }}</dd>
                <dt>Town:</dt>
                <dd>{{ location.town_city }}</dd>
                <dt>County:</dt>
                <dd>{{ location.county }}</dd>
                <dt>Telephone:</dt>
                <dd>{{ location.tel }}</dd>
                ###### ect #####
    </div>
</div>
<form action="" method="post">{% csrf_token %}
        {{ form.as_p }}
        <input type="submit" value="update" />
    </form>    
like image 505
Chris Meek Avatar asked Sep 24 '14 09:09

Chris Meek


1 Answers

I see a few problems:

  1. Your update view is exactly like your create view.
  2. You are passing the UpdateView class as the form in your update view.

If you are going to use an update view, you don't need to wrap it in another view or use it as a form, it is entirely self-contained.

In your views.py (not forms.py):

from .models import Location
from .forms import LocationForm

class LocationUpdateView(UpdateView):
    model = Location
    template_name = 'locations/location_update.html'
    form_class = LocationForm
    success_url = '/accounts/loggedin/locations/all/'

In your urls.py:

url('location/update/(?P<pk>\d+)/$', LocationUpdateView.as_view(),
                                     name='location-update'),

If you wire it up like this, you need to call the update view with the primary key of the location object you want to update. This will make sure that the form is populated with the data; so call it like this <a href="{% url 'location-update' pk=1 %}">update location id 1</a>.

If you do not want to use the class based view, then your view should be updated to load the data first, populate the form, then send the form to the user, and just like the UpdateView above, you need to pass in the primary key (or other reference), to load the object for which you are editing the record:

def update_location(request, pk=None):
    obj = get_object_or_404(Location, pk=pk)
    form = LocationForm(request.POST or None,
                        request.FILES or None, instance=obj)
    if request.method == 'POST':
        if form.is_valid():
           form.save()
           return redirect('/accounts/loggedin/locations/all/')
    return render(request, 'locations/location_update.html', {'form': form})
like image 128
Burhan Khalid Avatar answered Sep 30 '22 12:09

Burhan Khalid