Getting the "Real" Foreign Key from a ModelForm

144 views
Skip to first unread message

llanitedave

unread,
Jul 28, 2014, 9:39:05 AM7/28/14
to django...@googlegroups.com
This is my first attempt at a work Django Application since the tutorial, so my odds of missing something obvious are pretty high.  Still, I've been as far as I can in the documentation, and I can't find anything that addresses this.  Using Python 2.7 and Django 1.6.5, in a ModelForm containing a foreign key, rather than returning the key value itself the form returns an object that represents the __unicode__(self) value of the model.  So it isn't an integer of a string, and I get a TypeError when I try to save it.

class Pad_info(models.Model):

    site_id = models.IntegerField(primary_key=True)
    name = models.CharField('Pad Location', max_length=40, unique=True)
...
(irrelevant fields snipped...)
   


    def __unicode__(self):
        return u'%s, %s' % (self.site_id, self.name)
    
    def ID(self):
        return self.site_id

    class Meta:
        db_table = 'pad_info'
        verbose_name = 'Pad Info'


class Inspections(models.Model):
    of_pad = models.ForeignKey(Pad_info)
    insp_date = models.DateField('Inspection Date')
    agency = models.CharField('Agency/ Organization', max_length=40)
    lead_inspector = models.CharField('Lead Inspector', max_length=40)
    accepted = models.BooleanField(default=False)
    comments = models.TextField('Comments/ Notes')

    def __unicode__(self):
        return self.agency

    def ID(self):
        return self.id

    class Meta:
        db_table = 'inspections'
        verbose_name = 'Pad Inspection'


Here's my form:

from django import forms
from django.forms import ModelForm
from django.forms.fields import DateField
from reclamationdb.models import Inspections


class create_insp_m(ModelForm):
    class Meta:
        model = Inspections
        fields = ['insp_date', 'of_pad', 'agency', 'lead_inspector', 'accepted', 
                'comments']


And here's my view, still under construction:

def inspectioncreate_m(request):
    if request.method == 'POST':
        form = create_insp_m(request.POST)
        if form.is_valid():
            # create new inspection record
            insp_date = form.cleaned_data['insp_date']
            of_pad = form.cleaned_data['of_pad']
            agency = form.cleaned_data['agency']
            lead_inspector = form.cleaned_data['lead_inspector']
            accepted = form.cleaned_data['accepted']
            comments = form.cleaned_data['comments']
            
            # find if there is a record that matches pad_id
            try:
                checkPad = Pad_info.objects.get(pk=of_pad)
                newrecord = Inspections(of_pad, insp_date, agency, lead_inspector, accepted, 
                            comments)
                newrecord.save(force_insert=True)
                
            except Pad_info.DoesNotExist:
                # display error message and blank the pad_id field
                pass
                
            return render(request, 'reclamationdb/inspectioncreate_mobile.html', {'form' : form,})
            #return HttpResponseRedirect('/index/')
        
        else:
            # invalid form
            pass
    else:
        # do something else
        form = create_insp_m()
        #return render(request, 'reclamationdb/inspectioncreate_mobile.html', {'form' : form,})
        
    return render(request, 'reclamationdb/inspectioncreate_mobile.html', {'form' : form,})

The form appears in a web page, and displays all the required information, including the data from the related one record in the foreign key.
But when I save, I get a Type Error, reading "int() argument must be a string or a number, not 'Pad_info'".

The traceback that's highlighted is the line "checkPad = Pad_info.objects.get(pk=of_pad)"

 And in the list of local variables, the relevant one seems to be:
"of_pad  <Pad_info: 41, N. EZ Jr>"

It's an object rather than a string, and I can't seem to filter out just the number 41, which is the actual content of pad_id, and the value I'm trying to save in the foreign key field. This is really driving me crazy!

Thanks!

Dave


Tom Evans

unread,
Jul 28, 2014, 10:46:11 AM7/28/14
to django...@googlegroups.com
This is where your code is going wrong - you should not create a model
instance by passing positional arguments. The docs instruct you to use
kwargs, and then Django can assign to the correct fields.

Hence "of_pad" is of the correct type, it is just being applied to the
wrong field.

You can use kwargs, but it is much cleaner and less typing to use
Model.objects.create() as you can omit the subsequent save() as
create() creates valid objects (they have pks).

Cheers

Tom

Daniel Roseman

unread,
Jul 28, 2014, 2:17:16 PM7/28/14
to django...@googlegroups.com, teva...@googlemail.com
On Monday, 28 July 2014 15:46:11 UTC+1, Tom Evans wrote:
<snip>


You can use kwargs, but it is much cleaner and less typing to use
Model.objects.create() as you can omit the subsequent save() as
create() creates valid objects (they have pks).


You're right as far as that goes, but note that OP is using a ModelForm: so there is an even easier method.

    form = create_insp_m(request.POST)
    if form.is_valid():
        insp = form.save()

that way they can get rid of all the stuff involving `cleaned_data`, and even the querying for the Pad object, as the ModelForm does it all already.
--
DR.

llanitedave

unread,
Jul 28, 2014, 10:44:50 PM7/28/14
to django...@googlegroups.com, teva...@googlemail.com
Ahhh...  That sounds good.  Too easy, in fact.  I can't wait to give it a try!

Thanks!
Reply all
Reply to author
Forward
0 new messages