views:

75

answers:

1

Hi,
I can't see why in my application i am getting this error. As all primary keys are text fields are integers. Here is my code:
forms.py

 class EventAttendForm(forms.Form):
     talk = forms.ModelChoiceField(queryset=Talk.objects.all())
     membersAttended = forms.ModelMultipleChoiceField(queryset=Member.objects.all())

models.py

 class Talk(models.Model):
     title = models.CharField(max_length=200, primary_key=True)  
 class Member(models.Model):
     name = models.CharField(max_length=200)
     membership_number = models.CharField(max_length=200, primary_key=True)
     talks = models.ManyToManyField(Talk, through='Event_Attendance')
 class Event_Attendance(models.Model):
     talk = models.ForeignKey('Talk')
     membersAttended = models.ForeignKey('Member')

views.py

 def addAttendance(request):
     #eventAttendanceForm
     if request.method == 'POST':
          eventAttendForm = EventAttendForm(request.POST)
      for member in request.POST['membersAttended']:
            ea = Event_Attendance(request.POST['talk'], member)
            ea.save()
    return HttpResponseRedirect('../../../talks/')      
else:
    eventAttendForm = EventAttendForm()
    return render_to_response('attendance/addAttendance.html',{'eventAttendForm': eventAttendForm})

I cannot see why I am getting this error. The exact error is:

 Exception Type:    ValueError
 Exception Value:   invalid literal for int() with base 10: 'redirectTest'

RedirectTest is a Talk that I created with my form for the add talk to check that redirection was working correctly. The line of code that it is saying is causing the problem is ea.save()
Thanks in Advance,
Dean

+2  A: 

Consider the line

ea = Event_Attendance(request.POST['talk'], member)

You are creating an instance of the model Event_Attendance. The constructor expects the first argument to be an instance of Talk. Instead you are supplying it with a string which is the title of the talk.

A quick fix would be to look up the Talk instance with the matching title and pass it as an argument to the constructor. Something like this:

talk = Talk.objects.get(title = request.POST['talk'])
ea = Event_Attendance(talk = talk, membersAttended = member)
ea.save()

This will work but is not the best way to go about it. For one, the first line can always raise a DoesNotExist if a Talk with the given title is not found. Second you are accessing the POST variables directly rather than using the Form to validate them.

A better answer would therefore be:

eventAttendForm = EventAttendForm(request.POST.copy())
if eventAttendForm.is_valid():
    talk = eventAttendForm.cleaned_data['talk']
    membersAttended = eventAttendForm.cleaned_data['membersAttended']

    for member in membersAttended:
        ea = Event_Attendance(talk = talk, membersAttended = member)
        ea.save()
Manoj Govindan
Having tried this i am now getting this error: `int() argument must be a string or a number, not 'Talk'`
Dean
Thanks again for the new edit. Im still learning python(im moving from java). :)
Dean
Sorry, I missed out the keyword args! Fixed it.
Manoj Govindan