Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

python - Django Forms: Foreign Key in Hidden Field

My form:

class PlanForm(forms.ModelForm):    
    owner = forms.ModelChoiceField(label="",
                                  queryset=Profile.objects.all(),
                                  widget=forms.HiddenInput())
    etc...

    class Meta:
        model = Plan

Owner, in the model, is a ForeignKey to a Profile.

When I set this form, I set the value of "owner" to be a Profile object.

But when this comes out on the form, it seems to contain the name of the Profile like this:

<input type="hidden" name="owner" value="phil" id="id_owner" />

When the form is submitted and gets back to my views.py I try to handle it like this:

    form = PlanForm(request.POST)
    ...
    if form.is_valid():                
        plan = form.save()
        return HttpResponseRedirect('/plans/%s'%plan.id) # Redirect after POST

However, what I get is a type-conversion error as it fails to turn the string "phil" (the user's name that was saved into the "owner" field) into an Int to turn it into the ForeignKey.

So what is going on here. Should a ModelForm represent a foreign key as a number and transparently handle it? Or do I need to extract the id myself into the owner field of the form? And if so, how and when do I map it back BEFORE I try to validate the form?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I suspect that the __unicode__ method for the Profile model instance, or the repr thereof is set to return a value other than self.id. For example, I just set this up:

# models.py
class Profile(models.Model):
    name = models.CharField('profile name', max_length=10)

    def __unicode__(self):
        return u'%d' % self.id

class Plan(models.Model):
    name = models.CharField('plan name', max_length=10)
    profile = models.ForeignKey(Profile, related_name='profiles')

    def __unicode__(self):
        return self.name


# forms.py
class PlanForm(forms.ModelForm):
    profile = forms.ModelChoiceField(queryset=Profile.objects.all(),
            widget=forms.HiddenInput())

    class Meta:
        model = Plan

# views.py
def add_plan(request):

    if request.method == 'POST':
        return HttpResponse(request.POST['profile'])


    profile = Profile.objects.all()[0]
    form = PlanForm(initial={'profile':profile})
    return render_to_response('add_plan.html',
            {
                'form':form,
            },
            context_instance=RequestContext(request))

With that, I see PlanForm.profile rendered thus in the template:

<input type="hidden" name="profile" value="1" id="id_profile" />

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...