martincho
martincho

Reputation: 4717

Django how to override 'get_or_create' to create parent object if it doesn't exist

models.py

class Country(models.Model):

    code = models.CharField(max_length=2, unique=True)
    name = models.CharField(max_length=100)

    def __unicode__(self):
        return self.name

    class Meta:
        verbose_name_plural = 'countries'


class State(models.Model):

    country = models.ForeignKey(Country)
    code = models.CharField(max_length=5)
    name = models.CharField(max_length=40)

    def __unicode__(self):
        return self.name

I would like to be able to do something like this:

state, created = State.objects.get_or_create(name='myState',code='myCode',
                        country__code='myCountryCode',
                        country__name='myCountryName')

Now, my solution (not actually tried yet):

class StateManager(models.Manager):

    def get_or_create(self, **kwargs):
        country_data = {}
        for key, value in kwargs.iteritems():
            if key.startswith('country__'):
                country_data[key.replace('country__', '')] = value
        #will this work?
        country, created = Country.objects.get_or_create(country_data) 
        #get_or_create needs to be called here excluding 'country__' arguments 
        #and adding the 'country' object
        super(StateManager, self).get_or_create(modified_kwargs)

I would like if there is a better way of doing this in Django 1.6 before trying to make this code work.

Upvotes: 1

Views: 1422

Answers (1)

Bibhas Debnath
Bibhas Debnath

Reputation: 14939

Your solution will introduce a bunch of sources of error/exception. Why not just follow the standard procedure?

country, created = Country.objects.get_or_create(name='myCountryName', code='myCountryCode')
state, created = State.objects.get_or_create(country=country, name='myStateName', code='myStateCode')

Upvotes: 2

Related Questions