We have discussed how to create a Django project and Django app in our first Django tutorial. In this tutorial, we will talk about Django models. We will cover the following topics:

  • Creating a model.
  • Registering Model in django admin site.
  • 'Class Meta' in django models.
  • Creating Objects of Models
  • __str__ Method of django models.
  • get_absolute_url() method of django models.
  • @property in django model.
  • Django Model Fields

Model is a structure for storing data. The model handles everything related to data. Such as: data access, data validation, dealing with data of other models, etc.  It mirrors the fields and behaviors of the data. Generally a model is implemented as a python class which is a subclass of django.db.models.Model. Django gives an automatically-generated database-access API to create a table in our database by each model, and the "attributes" of the table are created by the "fields" of the model class. Models are defined inside an app’s ‘models.py’ file. 

After creating a project and an app & before starting writing codes in your first_app/models.py make sure you have these three things:

1. Your virtual environment is activated

2. You have registered your app in 'INSTALLED_APP' in "settings.py". 

3. You have created a Super User (admin) -

python manage.py createsuperuser

How to create Model in Django

In first_app/models.py

from django.db import models 


class Person(models.Model):     
    GENDER = (
              ('M', 'Male'),
              ('F', 'Female'),
             )     
    #Fields     
    first_name = models.CharField(max_length=30)                    
    last_name = models.CharField(max_length=30)     
    email = models.EmailField(unique = True)     
    gender = models.CharField(max_length=1, choices= GENDER)

After creating this model we will have to run migrations commands to convert these into database table:

python manage.py makemigrations 
python manage.py migrate
(env) my_project> python manage.py makemigrations 
Migrations for 'first_app':   
first_appmigrations001_initial.py  
                      - Create model Person
(env) my_project> python manage.py migrate 
Operations to perform:   
Apply all migrations: admin, auth, contenttypes, first_app, sessions Running migrations:   
Applying first_app.0001_initial... OK

Now, if you go to admin panel: http:127.0.0.0:8000/admin  (don't forget to run your server first; running the command 'python manage.py runserver'). You will be asked for admin username & password. Give the credentials of the user that you created using 'python manage.py createsuperuser'.

You will see django's default admin panel.

Django's Default Admin Panel

Registering Model in Django Admin Site.

There is no app named 'first_app' & no model. We will have to register this model in admn site. Go to your app's 'admin.py' file. and add the following codes.

from django.contrib import admin 
from first_app.models import Person   

# register your models here.   
admin.site.register(Person)

Now go to your admin panel:

'Class Meta' in Django Models.

See, We have named the model as ‘Person’ but Django is showing us the plural form “Persons”. Nothing seems wrong with that but think that you have a model named ‘Category’ Django will show that as “Categorys” in admin panel where it should be "Categories" in plural. To avoid this problem, we will have to write a Meta class in which we will define the model’s name in plural for us:

#Metadata 
class Meta:         
    verbose_name_plural = 'All Persons'

Add this piece of code inside your model class & refresh your admin panel. You will see the output:

This is not the end. You can also use more metadata (verbose_name, ordering, app_label, db_table etc )  about your 'Model' in Meta Class.

Creating Objects of Models

As our model is a “Python Class” we can create as many object of this class as we want. Let’s  create some objects.

Person Form

__str__ Method in Django Models.

We have created three objects of the ‘Person’ class. But how they are representing in the admin panel is not readable. Here we can use "__str__" method for string representation. We will override the default "__str__" method of ‘models.Model’ class in our ‘Person’ class. 

#Method     
def __str__(self):         
    return self.first_name + self.last_name

Now see output in admin panel. 

You can also return f-string…

def __str__(self):         
    return f'{self.first_name} {self.last_name}'

get_absolute_url() Method in Django model.

Till now we were working with model. Now we will do something with the instances of our model. If you need data about a single instance of our 'Person' class then you will have to fetch the data according to it's primary key or a unique key. Here, our primary key is 'id'. which is not shown in 'Person' class attributes but will be generated automatically. You can see it in your first_app/migrations folder.

So, to call the object a with its id we will have to define a function named 'get_absolute_url()'.

#methods
def get_absolute_url(self):
    """returns the url of an individual object of model."""
    return reverse('person-detail',kwargs={'pk': self.id})

When it comes to web development you really want to avoid hard coding paths in your templates. The reason for this is that paths might change, and it will be a hassle to go through all your HTML and templates to find every single URL or path and update it manually. It makes your code much harder to maintain.

<a href="{{person.get_absolute_url}}">Link</a>

@property

is a built-in decorator in Python.Python classes can treat a function as an attribute using the property decorator.Django models can also use it.
@property decorator is just an easy way to call the property() function, Which is used to return the property attributes of a class from the stated getter, setter and deleter as parameters. In our model we took first_name and last_name. Now if we want a users full_name then joining the first_name & last_name would be enough. So, we will right a function to join them...

@property     
def full_name(self):         
    return f'{self.first_name} {self.last_name}'

This means you can call full_name as if it were a member variable instead of a function. We can see the output in our admin panel. Add the following codes in admin.py.

class PersonAdmin(admin.ModelAdmin):     
    list_display = ['full_name','email','gender']        

# Register your models here.   
admin.site.register(Person, PersonAdmin)

Now, even if you remove the ‘__str__’ method you will still see the ‘full_name’ in your admin panel along with email & gender. Though email & gender are member variables and ‘full_name’ is a method.

Overall, our model will look like this:

from django.db import models
from django.urls import reverse

# Create your models here.
class Person(models.Model):
    GENDER = (
        ('M', 'Male'),
        ('F', 'Female'),
    )
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)
    email = models.EmailField(unique = True)
    gender = models.CharField(max_length=1, choices= GENDER)

    class Meta:
        verbose_name_plural = 'All Persons'

    @property
    def full_name(self):
        return f'{self.first_name} {self.last_name}'

    def __str__(self):
        return f'{self.first_name} {self.last_name}'

    #methods
    def get_absolute_url(self):
        """returns the url of an individual object of  model."""
        return reverse('person-detail',kwargs={'pk': self.id})

Django Model Fields

In our example, we have used CharField & EmailField. But there are different types of fields in Django. Here are some which are mostly used

Django Model Fields Data Type Description
models.BinaryField() Binary Stores binary data (e.g. images, audio or other multimedia objects)
models.BooleanField() Boolean Stores True/False (or 0/1) values
models.NullBooleanField() Boolean Works just like BooleanField but also allows NULL values
models.DateField() Date/time Creates a date field to store dates
models.TimeField() Date/time Creates a time field to store times.
models.DateTimeField() Date/time Creates a datetime field to store dates with times
models.DurationField() Date/time Creates a field to store periods of time.
models.AutoField() Number Creates an integer that autoincrements, primarly used for custom primary keys
models.DecimalField() Number Stores a number. Takes two arguments; (decimal_places=  X, max_digits=Y )
models.FloatField() Number Stores floating-point numbers.
models.IntegerField() Number Stores integer numbers.
models.PositiveIntegerField() Number Works just like IntegerField but limits values to positive numbers from 0 to 2147483647
models.CharField(max_length=N) Text Creates a text column, where the 'max_length' argument is required to specify the maximum length in characters.
models.TextField() Text Used to store text.
models.EmailField() Text (Specialized) Uses Django EmailValidator to determine what is and isn't a valid.
models.FileField() Text (Specialized) Used for handling files (e.g. opening/closing file, upload location,etc).
models.ImageField() Text (Specialized) Used for handling image files (e.g. getting the height & width) Works just like Note:  this field requires the Pillow Python library (e.g. pip install Pillow).

[/pl_text]
[/pl_col]
[/pl_row]

+ posts

Author | Python-Django Developer

+ posts

Full-stack Developer (Python | Django | React | React-Native | Angular | Vue)