3

I feel like I am missing some very basic point, but can't solve this.
Let's say I have model like this one:

class Person(models.Model):
    first_name = models.CharField(max_length=256, blank=True)
    # this is weird field, but needed for my usecase
    last_name = models.WeirdCustomField(max_length=256, blank=True)

And there is a form for this, which I would like to customize a bit (comments):

class PersonForm(forms.ModelForm):

    class Meta:
        model = Address
        # I want to override 'last_name' field, so exclude it here
        exclude = ['last_name']

    # And add additional field
    my_field = ChoiceField(choices=list_of_choicec)
    last_name = forms.CharField()

    def __init__(self, *args, **kwargs):
        last_name = kwargs.pop('last_name', None)
        my_field = kwargs.pop('my_field', None)
        super(PersonForm, self).__init__(*args, **kwargs)
        self.fields['last_name'] = last_name
        self.fields['my_field'] = my_field

Now, in the shell (after all imports...)

person = Person.objects.get(first_name='Jacob')
person.first_name # Prints 'Jacob', correct!
form = PersonForm(instance=person, last_name='Smith', my_field='test123')
form['first_name'].value() # -> 'Jacob', that's right
form['last_name'].value() # -> nothing, I expected 'Smith'
form['my_field'].value() # -> nothing, I would like to see 'test123'

I think I dig Internet very deep, but could not find solutions for this kind of problem.

1 Answer 1

7

You have to set the initial value. In your init try replace with below code.

self.fields['last_name'].initial = last_name
self.fields['my_field'].initial = my_field

The initial can also be passed when the form instance is created.

form = PersonForm(instance=person, initial={'last_name'='Smith', 'my_field'='test123'})

This one is the recommended way to do it. Don't have to override the init method at all.

Sign up to request clarification or add additional context in comments.

4 Comments

Amazing, I don't think I would figure it out myself in the near future, thank you! I also need to say, it is quite counter intuitive, but I guess it's the framework way.
try printing self.fields['my_field'] in your init. You can see what it is.
how to perform this in generic views ??
Which generic view are you using ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.