bharal
bharal

Reputation: 16164

django - how can i add a new value to an extant modelForm?

so i have a model form - this is for django's incredibly unintuitive editing-of-a-model process, and if anyone has a solid "for an idiot" tutorial, i'd be keen to hear about it!

The problem at hand is adding/setting a value to a modelForm field so that it shows up in the html.

SO, i have this code in my view logic:

class EditSaveModel(View):

    def get(self,request,id=None):
        form = self.getForm(request,id)
        return self.renderTheForm(form,request)

    def getForm(self,request,id):
        if id:
            return self.idHelper(request,id)
        return PostForm()

which is called on a "get". So, here, I am either wanting to show a pre-completed form, or a new form!

Drilling into the idHelper:

    def idHelper(self,request,id):
        thePost = get_object_or_404(Post, pk=id)
        if thePost.story.user != request.user:
            return HttpResponseForbidden(render_to_response('errors/403.html'))
        postForm = PostForm(instance=thePost)
        postForm.fields.storyId.value = thePost.story.id **ANY NUMBER OF COMBOS HAVE BEEN TRIED!
        return postForm

where i am getting a post object, checking it belongs to the active user, and then attaching a new value to it - the "storyId"

i also tried, above:

    postForm.storyId.value = thePost.story.id 

but that tells me that postForm has no storyId value to set!

and:

    postForm.storyId = thePost.story.id 

but that doesn't actually set the storyId - that is, in the html, no value is present.

having a look at my PostForm definition:

class PostForm(forms.ModelForm):
    storyId = forms.IntegerField(required=True, widget=forms.HiddenInput())

    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop('request', None)
        super(PostForm, self).__init__(*args, **kwargs)

    class Meta:
        model = Post
        ordering = ['create_date']
        fields = ('post',)

    #some validation here!
    #associates the new post with the story, and checks that the user adding the post also owns that story
    def clean(self):
        cleaned_data = super(PostForm, self).clean()
        storyId = self.cleaned_data.get('storyId')
        storyArray = Story.objects.filter(id=storyId,user=self.request.user.id)
        if not len(storyArray): #eh, this means if self.story is empty.
            raise forms.ValidationError('Whoops, something went wrong with the story you\'re using . Please try again')
        self.story = storyArray[0]
        return cleaned_data

right, so is this clear? To summerise:

I want a hidden storyId field attached to my PostForm, so that i always know which story a given post is attached to! Now, i know there might be other ways to do this - i might be able to add the foreignkey as "hidden" somehow? that is welcome, please tell me how! But i really want to have the foreignKey as a hidden field right now, so feel free to propose a different way, but also answer the foreignkey as hidden modelForm question too!

With all the code above, i would imagine that I can just have this in the html (because my form is definitely called "form"):

{% for hidden in form.hidden_fields %}
    {{ hidden.errors }}
    {{ hidden }}
{% endfor %}

or even

{{ form.storyId }}

but this doesn't work! storyId will never show up as a set value.

what is going on here?

Upvotes: 0

Views: 179

Answers (1)

dgel
dgel

Reputation: 16796

Have you tried passing it in to the constructor?

def __init__(self, *args, **kwargs):
    self.request = kwargs.pop('request', None)
    self.story_id = kwargs.pop('story_id', None)
    super(PostForm, self).__init__(*args, **kwargs)
    self.fields['storyId'].initial = self.story_id

Upvotes: 1

Related Questions