iducam
iducam

Reputation: 79

How can I access parent model fields in a form using the child model?

For context, I'm trying to create a form that allows users to upload info about their own custom Pokemon. Basically, they are creatures that you can catch, name, and level up. To draw a comparison, it is a similar concept to dogs; there are labradors, German Shepherds, huskies, etc. that would be variations of a base Dog model, but then each individual would have a name and other defining characteristics.

I've created Pokemon and CustomPokemon models and imported the latter into my forms.py file. I'm trying to access some parent fields but am unable to:

from django import forms

from .models import CustomPokemon

class PokemonForm(forms.ModelForm):
    class Meta:
        model = CustomPokemon
        fields = ['pokemon.poke_name', 'name', 'level']

The poke_name field is inherited from the parent Pokemon model while the other two fields belong to the CustomPokemon model. I'm getting this FieldError:

Unknown field(s) (pokemon.poke_name) specified for CustomPokemon.

The issue isn't resolved by using poke_name, so I'm curious how I can access the parent model's fields so they can be displayed in the form.

Upvotes: 1

Views: 1218

Answers (1)

David Duran
David Duran

Reputation: 1826

First option

If you just want a dropdown displaying the field poke_name, what you could do is to define a __str__ method inside Pokemon model like this:

class Pokemon(model.Model):
    ...
    def __str__(self):
        return self.poke_name

Then, you can define the form as follows:

class PokemonForm(forms.ModelForm):
    class Meta:
        model = CustomPokemon
        fields = ['pokemon', 'name', 'level']

And you will get a dropdown displaying all the poke_name of your database, where you can choose your foreign key. It would be better if poke_name is a unique field so that the foreign key can be clearly identified.

Second option

If you need more freedom, you could manually define a custom field as follows:

class PokemonForm(forms.ModelForm):
    poke_name = forms.CharField()

    class Meta:
        model = CustomPokemon
        fields = ['name', 'level']

Then, when validating the form, you should take care of whether the entry exists and/or create it:

if form.is_valid():
    form.instance.pokemon = Pokemon.objects.get_or_create(cname=form.cleaned_data['poke_name'])
    form.save()

Upvotes: 2

Related Questions