1

This ties into mt question from earlier. I've looked a few answers to similar issues, but I'm not sure how they apply here.

I'm trying to use GET methods to creat content on a Django Webserver. When i type the following url:

 http://127.0.0.1:8000/maps/createEvent/?name=explosion&reporter=nathaniel&description=something%20exploded&lat=99&lon=99&timestamp=2434253

I get this error:

    invalid literal for int() with base 10: 'explosion'
Request Method: GET
Request URL:    http://127.0.0.1:8000/maps/createEvent/?name=explosion&reporter=nathaniel&description=something%20exploded&lat=99&lon=99&timestamp=2434253
Django Version: 1.5.2
Exception Type: ValueError
Exception Value:    
invalid literal for int() with base 10: 'explosion'

Here's the url in question:

url(r'^createEvent/$', views.createEvent, name='createEvent')  

And the View:

def createEvent(request):
e = Event(request.GET['name'],request.GET['reporter'],request.GET['description'],
           request.GET['lat'],request.GET['lon'],request.GET['timestamp'])
e.save()

return HttpResponseRedirect(reverse('maps:event_detail', args=(e.id,)))
Nathaniel D. Waggoner
  • 2,856
  • 2
  • 19
  • 41

1 Answers1

1

First add a get_absolute_url method to your Event model:

class Event(models.Model):
    # your fields go here

    def get_absolute_url(self):
       return reverse('maps:event_detail', self.pk)

You need to do something like this:

from django.shortcuts import redirect

def createEvent(request):
   e = Event.objects.create(name=request.GET.get('name'),
                            reporter=request.GET.get('reporter'),
                            description=request.GET.get('description'),
                            lat=request.GET.get('lat'),
                            lon=request.GET.get('lon'),
                            timestamp=request.GET.get('timestamp'))

   return redirect(e)

create will automatically save the object; and the redirect shortcut automatically uses the get_absolute_url method if passed an instance of a model.

Or, you can use a ModelForm - if this is something the user is entering:

In a file called forms.py, add this:

from django import forms
from .models import Event

class EventForm(forms.ModelForm):
    class Meta:
        model = Event

Now your view becomes very simple:

from django.shortcuts import render
from .forms import EventForm

def createEvent(request):
    form = EventForm(request.POST)
    if form.is_valid():
       e = form.save()
       return redirect(e)
    return render(request, 'form.html', {'form': form})

Your template (the form.html) now is:

<form method="POST">
    {% csrf_token %}
    {{ form }}
    <input type="submit">
</form>

As this is a common pattern (creating new things for models), django provides a generic CreateView to speed things up:

from django.generic.views import CreateView

class CreateEvent(CreateView):
     model = Event
     template_name = 'form.html'

All the above code snippets do the exact same logic (except for the first one, which just saves an object). As you can see, django provides quick shortcuts for common tasks.

Burhan Khalid
  • 169,990
  • 18
  • 245
  • 284
  • Hey,thanks for this! It's a great answer. Turns out the actual bug I'm facing is the key value pairing from your createEvent() example. I figured that out last night, but since you got that+ about a dozen other thigns I'm going to call it answered. If you want to edit it to specifically point out my syntax error I'll accept. – Nathaniel D. Waggoner Sep 08 '13 at 15:47