Question

There is something that is tripping me up with models, and I guess SQL tables in general.

Let us suppose you have these models:

class Manufacturer(models.Model):
    name = models.CharField()
    company_created = models.CharField()

class Car(models.Model):
    manufacturer = models.ForeignKey(Manufacturer)

When you create an instance of Car like say, the following

civic = Car(manufacturer='honda')

A couple questions:

  1. When you create an instance of Car, are you also creating an instance of Manufacturer as a by-product? Or does 'honda' need to exist as an instance already. If not, is there a way to make an instance of both, in say, one form.
  2. Can I make calls on 'civic' for things pertaining to the manufacture? For example, could I get the 'company_created' data from the civic instance? If not, why bother having the relationship in the first place?

Thanks so much in advance. I would really appreciate a thorough answer so I can understand models and relationships fully. And yes, I have read the docs.

Was it helpful?

Solution

Firstly, the thing to remember is that these classes are representations of underlying database tables. A ForeignKey field in a Django model represents a one-to-many relationship in the database, with an _id field representing the ID of another table. Those tables are themselves independent, but are linked via the FK field (and the relevant index constraint, if the database supports them).

That said, in your Car model manufacturer is a required field (because you haven't defined it as null=True). So when you create a Car, you must point it at an already existing Manufacturer - and that manufacturer must have been saved already, so that Django can populate the underlying manufacturer_id field with the ID of the related object

Because Django is aware of the foreign key relationship between the two objects, you can use them when querying. In SQL this would be done via JOINs: Django gives you a special syntax to do queries across those joins, via double underscores. So, for example, if you wanted to get all the cars made by a manufacturer created in 1990 (assuming that's what you mean by the company_created field), you would do this:

Car.objects.filter(manufacturer__company_created='1990')

Django translates this into something like":

SELECT * from car JOIN manufacturer ON car.manufacturer_id=manufacturer.id WHERE manufacturer.company_created='1990';

If you already have your "civic" instance and just want to get access to the related data, this is pure Python object access: civic.manufacturer is the related Manufacturer object, so you can simply do civic.manufacturer.company_created to get the relevant data. Again, Django translates that into the database access, but from your point of view this is simple object composition.

Note that really all this is fully explained in the tutorial, with relationships between Poll and Choice which exactly match your Manufacturer and Car models.

OTHER TIPS

Yes manufacturer need to exist as an instance already.

you can create car instance like this:

manuf= Manufacturer(name='honda',company_created='Benz')
manuf.save()

civic = Car(manufacturer=manuf)

you can get the company_created data from the civic instance by:

civic.manufacturer.company_created
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top