Models in Django
Tags: django, webdev, python
Published: 2023-01-17 12:42:52

One of the key features of Django is it use of models, which are used to represent the data in a Django application. Now before we move, this is a continuation of my Django Basics series, you can read them [here](https://dev.to/akolade)

### What are Models

Models in Django are defined as Python classes that inherit from the **django.db.models.Model** class. Each class represents a table in the database, and each attribute of the class represents a column in the table.

did I lose you with that definition? okay, let's make it simpler

Model is a python class that defines the fields and behavior of the data you will be storing. these python classes or models are defined in the models.py file of your app and are used to structure and interact with the database.

Django provides a built-in Object-Relational Mapping (ORM) system, which allows you to interact with the database using Python code instead of writing raw SQL queries. This means that you can create, read, update, and delete database records using Python methods

### Creating a Model

It is quite easy to create a model just like defining a class in python, but there is more to it, we also need to define the fields in the model. for example, if you were building a simple blog application, you might have a model for the blog posts, which would look something like this:

```python
from django.db import models

class Author(models.Model):
    name = models.CharField(max_length=255)
    bio = models.TextField()
    email = models.EmailField()
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
     def __str__(self):
        return self.name

class Post(models.Model):
    title = models.CharField(max_length=255)
    content = models.TextField()
    pub_date = models.DateTimeField()
    author = models.ForeignKey(Author, on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
     def __str__(self):
        return self.title
```

This model defines two classes: `Author` and `Post` which both inherit from `models.Model`, this tells Django that the classes should be treated as models and that they should be stored in the database.

**Author** class defines the fields and behavior of the Author data and it has 5 fields:

* `name`: This is a `CharField` which is used to store character data (i.e. strings) in the database. The `max_length` parameter specifies the maximum number of characters that can be stored in this field.
    
* `bio`: This is a `TextField` which is used to store large amounts of text in the database.
    
* `email`: This is a `EmailField` which is used to store email addresses, it will validate the email format.
    
* `created_at`: This is a `DateTimeField` which is used to store date and time information, the `auto_now_add` argument is set to `True` which means that the field will be set to the current date and time when the model instance is first created.
    
* `updated_at`: This is a `DateTimeField` which is used to store date and time information, the `auto_now` argument is set to `True` which means that the field will be set to the current date and time every time the model instance is saved.
    

**Post**: This class defines the fields and behaviour of the Post data. it has six fields

* `title`: This is a `CharField` which is used to store a short title for the post.
    
* `content`: This is a `TextField` which is used to store the content of the post.
    
* `pub_date`: This is a `DateTimeField` which is used to store the publication date and time of the post.
    
* `author`: This is a `ForeignKey` which is used to establish a one-to-many relationship between the `Post` model and the `Author` model. It means that each post is associated with a single author.
    
* `created_at` and `updated_at`: the same meaning as that of Author
    

### Model Method

Both classes define a `__str__` method, which returns a string representation of the object, this method is used when the object is displayed in the Django admin interface or when the object is returned by a query.

### Django Fields

For better understanding, it is necessary to define what those fields we just use are and also state some examples

Fields are used to define the data that a model should store.

The field class defines the type of data that the field will store, as well as any constraints or validation that should be applied to that data. The data for each field is stored in the corresponding database table, fields are used to define the structure of the table and the type of data that is stored in each column.

### Types of Fields

Django provides a variety of built-in field classes for common data types such as text, numbers, dates, and files. Some examples of these field classes are:

* `CharField`: used to store character data, such as a name or a title.
    
* `TextField`: used to store large amounts of text, such as a blog post or a description.
    
* `IntegerField`: used to store integers, such as the number of views or likes on a post.
    
* `DateField`: used to store a date without a time.
    
* `DateTimeField`: used to store a date and time.
    
* `DecimalField`: used to store decimal numbers, such as currency values.
    
* `FileField`: used to store files, such as images or documents.
    
* `ImageField`: used to store images, this field is a subclass of `FileField` with some additional validation for image file types.
    

Each field class has its own set of optional arguments that can be used to customize its behavior. Some of the most common arguments are

* `max_length`: This argument is used to specify the maximum number of characters that can be stored in a field. It is typically used with `CharField` and `TextField` fields.
    
* `default`: This argument is used to specify a default value for the field. This value will be used when creating a new model instance if no value is provided for the field. It can be a value or a callable that returns a value.
    
* `null`: This argument is used to specify whether or not the field can be empty (`NULL`) in the database. The default value is `False`, which means that the field cannot be empty.
    
* `blank`: This argument is used to specify whether or not the field can be left blank in forms. The default value is `False`, which means that the field must be filled in when the form is submitted.
    
* `choices`: This argument is used to specify a list of valid choices for the field. It should be a list of 2-tuples, where the first element is the value to be stored in the database and the second element is the human-readable label.
    
* `auto_now`: This argument is used to automatically set the field to the current date and time every time the model instance is saved.
    
* `auto_now_add`: This argument is used to automatically set the field to the current date and time when the model instance is first created.
    
* `on_delete` : is used to specify what should happen when the referenced object (i.e. the object on the other side of a foreign key or many-to-many relationship) is deleted. It is used in fields such as `ForeignKey` and `OneToOneField` and it is a required argument.
    

You can also use fields to establish relationships between models, for example, you can use a `ForeignKey` field to establish a one-to-many relationship between two models, or you can use a `ManyToManyField` to establish a many-to-many relationship.

---

Since you got to this point, now let's re-create the Post model again and add more structure and fields.

```python
class Post(models.Model):

    options = (
    ('draft', 'Draft'),
    ('published', 'Published'),
    )

    title = models.CharField(max_length=255, unique=True)
    content = models.TextField()
    pub_date = models.DateTimeField()
    author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name='Posts')
    slug = models.SlugField(max_length=255, unique_for_date='publish')
    status = models.CharField(max_length=16, choices=option, default='draft')
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)


    def __str__()
        return self.title

    class Meta:
        ordering = ('-publish',)
```

Now let me explain:

* `options` : A tuple of tuples that define the valid options for the `status` field, the first element of each tuple is the stored value in the database and the second is the human-readable label.
    
* `title`: A `CharField` that is used to store the title of the article. The `max_length` argument is set to 255 characters and the `unique` argument is set to `True`, this means that the title must be unique among all articles.
    
* `slug`: A `SlugField` that is used to store a short, URL-friendly version of the title. The `max_length` argument is set to 255 characters, and the `unique_for_date` argument is set to `'publish'`, this means that the slug must be unique among all articles for a given date.
    
* `author`: A `ForeignKey` that is used to establish a relationship between the `Post` model and the `Author` model. This field is used to store the Author who created the article, the `on_delete` argument is set to `models.CASCADE`, which means that when the user is deleted, all the articles associated to him will be deleted as well.
    
* `status`: A `CharField` that is used to store the current status of the article, such as 'draft' or 'published'. The `max_length` argument is set to 16 characters, the `choices` argument is set to `options`, this means that the valid choices are the ones defined in the options tuple and the `default` argument is set to 'draft', which means that if no status is specified, the default status will be 'draft'.
    

Wow, you made it here. Thank you.

In the next article, I will write about databases - types, configuration and migration  
**Till Then ----- Happy Coding**