1

I was looking at

from django.db import models class Publisher(models.Model): name = models.CharField(max_length=30) address = models.CharField(max_length=50) city = models.CharField(max_length=60) state_province = models.CharField(max_length=30) country = models.CharField(max_length=50) website = models.URLField() class Author(models.Model): first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=40) email = models.EmailField() class Book(models.Model): title = models.CharField(max_length=100) authors = models.ManyToManyField(Author) publisher = models.ForeignKey(Publisher) publication_date = models.DateField() 

which is an example taken from djangobook.com and I was confused about what the models.Model argument. I get that models is a class with methods such as CharField(), which is being inherited into these classes in order to create table columns...right? But where does the "Model" part of models come in to this? Whats it for? where abouts is it needed?

Any analogies or explanations coming from you would be appreciated, as i have been looking on the internet and still am confused. Sorry for the ignorantly phrased question.

Thanks!

3
  • 2
    modules (lower case) is a module, while Models (upper case) is a class name inside that module. It is likely that CharField, URLField, etc are also classes inside the models module. Commented Sep 21, 2013 at 19:38
  • Why is the class name "Models" (uppercase) there? whats it used for if the module "models" (lowercase) contains the classes CharField(), etc. Commented Sep 21, 2013 at 19:43
  • 2
    Q1) Because that's Python's way of specifying inheritance / defining a subclass. So in the file you've shown, it's saying that Publisher should be a subclass of Model, a class defined in the model module. Q2) It's there for a different reason than the model.CharField(). It's there to define the superclass of the Publisher class, while model.CharField() is there to say that that class's member (e.g. name, city, etc) should be an instance of the CharField class, which is defined in the model module. Commented Sep 21, 2013 at 19:49

1 Answer 1

2

I get that models is a class with methods such as CharField(), which is being inherited into these classes in order to create table columns...right?

I believe you took a wrong turn at Albuquerque. Lowercase models is not a class and CharField() is not a method, though it does end up calling a particular method called __init__() but we'll get to that in a bit.

First, look at the import statement:

from django.db import models 

Lowercase models here is a package, meaning it is a directory containing an __init__.py file. Specifically, it is a sub-package of the package db, which is itself a sub-package of the django package. The Python dotted path parallels the package directory structure.

It is worth noting here that models is NOT a module, though it COULD have been. If there were a Python file named models.py within the db package, then models would have been a module. How do we know for sure? By perusing the Django source code, we find that it is a directory, and thus a package. See the source code here.

So, packages are directories containing either: other directories (sub-packages) or python files (modules). Class definitions are defined in the modules. Ok, then how is the Model class imported from models if it is a package and not a module?

This is possible because the __init__.py file in the models package imports the Model class. The Model class definition actually lives in the base module, yep the base.py file within the models package.

Now, for the CharField(). In Python, class instantiation uses the function notation. When defining your custom Model classes, the database fields are created from your model's class attributes. Within the Book model, title is a class attribute, instantiated from the CharField class. When it is instantiated, the CharField method __init__() is called.

And here is a good place to point out why it is handy to have packages for making imports more convenient. The CharField class is defined within the fields sub-package of the models package, and many of Django's other field classes are defined there as well. Similar to how __init__.py in the models package imported the Model class from the base sub-module, it also imports all the fields from the fields sub-module.

Since the models package takes care of all the sub-imports we'll likely need to use, we can just import that package. Using the from style import, we can easily identify all the places in our code where we are using something from that package, since it always has the dot notation models.Something. We don't have to worry about how all that stuff is organized in the package.

For more details, see the Python documentation on packages.

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.