Notes on Chapter 5 of Tango With Jango2 -- Model & DB

Django uses object relational mapper (ORM) ¹ To access the data stored in the database

In essence, the data stored in the database table is encapsulated by the Django model. A model is a python object that describes database table data. Django provides some methods that allow you to manipulate data through corresponding Python model objects, rather than directly operating the database through SQL. Any command you issue to ORM will be automatically converted into the corresponding SQL statement.

[learning contents of this chapter] understand the basic knowledge of data management of Django and its ORM (i.e. database operation)

1. Recall the demand of Rango App

(1) Rango is essentially a web directory - a website that contains links to other external websites
(2) There are several different web page categories, and each category has no or one or more links (many-to-one relationship)
(3) 1 category – 1 name, multiple visits, multiple likes
(4) One page belongs to a specific category; 1 page – 1 title, 1 URL, multiple views

2. Tell the DB of Django project

Use default DB, i.e. setting DATABASE variable in py (as follows):

⚠️ Do not use git push DB
(adding db.sqlite3 to the. gitignore file will not git push; or *. pyc)

3. Create Models

Models are stored in workspace / Tango_ with_ django_ project/rango/models. In PY
Create models for category and page respectively, and the base classes are from Django db. models. Inheritance in Model

from django.db import models

# Create your models here.
class Category(models.Model):
    name = models.CharField(max_length=128, unique=True)
    # unique=True ⇒ setting the field name to unique means that the field can be used as the primary key

    def __str__(self):
        return self.name
    # If not__ str__ (), which will be displayed as < category: category object >
    # __ str__ () is toString() in Python

class Page(models.Model):
    category = models.ForeignKey(Category, on_delete=models.CASCADE)
    # The CASCADE instruction Django deletes the pages related to the category when the category is deleted
    title = models.CharField(max_length=128)
    url = models.URLField()
    views = models.IntegerField(default=0)

    def __str__(self):
        return self.title
Django built in field type

CharField: storage character type; max_length - specifies the maximum character length
URLField: store URL type; max_length - specifies the maximum character length
IntegerField: store int type
DateField: stores Python datetime Date object
If unique=True is set for each field, that is, the field name is set to be unique, which means that each category name must be unique, which means that this field can be used as the primary key
Each field can specify additional properties, such as default value (default='value '), empty (NULL =True), or not empty (NULL =False)

Fields of relationships between Django models

ForeignKey: one to many
OneToOneField: one to one
ManyToManyField: many to many

4. Create and migrate DB

(1) Initialize DB
To create the database and all related tables = > open the terminal / command prompt and navigate to the root directory of the project where the manage.py module is stored. Run the following command:

$ python manage.py migrate

Enter as follows:

(2) Create a superuser to manage the DB and execute the following commands:

$ python manage.py createsuperuser

Enter username, email address and password

[delete superuser]
Enter at the terminal:

$ python manage.py shell

#Then enter
>>> from django.contrib.auth.models import User
>>> User.objects.get(username='yfan',is_superuser=True).delete()
# Replace 'yfa' with your own user name
>>> exit()

(3) create & update Models/Tables
When you change the Models of the application, you need to use manage Py to register these changes, run the following command:

python manage.py makemigrations rango

The running result is shown in the following figure (after this command is completed, check the rango/migrations directory to see that a Python script named 0001_initial.py has been created, which contains all the necessary details required to create a database schema for this specific migration):

If you want to check the underlying SQL issued by Django ORM to the database engine for a given migration, you can issue the following command (rango is the name of your application, and 0001 is the migration of the SQL code you want to view):

$ python manage.py sqlmigrate rango 0001

(4) After you create migrations for your applications, you need to commit them to the database. Issue the migrate command again:

$ python manage.py migrate

The running result is shown in the following figure (this output confirms that the database table has been created in the database):

5. Django Models & Shell

You can interact with Django Model directly from the Django shell -- a very useful debugging tool
(1) To access the shell, we need to call manage again from the root directory of the Django project py
Execute the following command (this will launch a Python interpreter instance and load the project settings for you):

$ python manage.py shell


Enter the following code in the terminal to interact with the Model:

# Import Category model from Rango application
>>> from rango.models import Category 

# Show all current categories
>>> print(Category.objects.all())
# Because no category is defined, we get an empty QuerySet object
<QuerySet []> 

# Create a new category object and save it to the database
>>> c = Category(name='Test')
>>> c.save()

# Now list all the category objects stored once more.
>>> print(Category.objects.all()) 
# You'll now see a 'Test' category. 
<QuerySet [<Category: Test>] 

# Quit the Django shell.
>>> quit()

6. Configure Admin interface

[two Model management interfaces will be set]
(1) Run the following command to access http://127.0.0.1:8000/admin/ , log in with the previously set superuser

$ python manage.py runserver


Missing Category and page models defined for Rango = > let Django know we want to include them
(2) Open Rango / Admin Py file. Use admin site. Register () method registers the classes to be included:

from django.contrib import admin 
from rango.models import Category, Page
admin.site.register(Category) 
admin.site.register(Page)

Re runserver and you will see two models: Category & page. Click category to see the Test Category:

Delete Test Category
The spelling error of Categorys in the management interface can be used as verbose_name_plural modification:

class Category(models.Model):
	name = models.CharField(max_length=128, unique=True)

class Meta:
	verbose_name_plural = 'Categories'

def __str__(self):
	return self.name

7. Create a fill script

Adding data to the DB using the fill script
(1) In workspace / Tango_ with_ django_ Create a file named populate in the project / directory_ rango. Py new file
(2) populate_rango.py content:

import os 
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'tango_with_django_project.settings')

import django 
django.setup() 
from rango.models import Category, Page 

# Populate() keeps tab s on the created categories.
# For example, a reference to a new category is stored in the local variable c.
# This is because Page needs Category reference. Calling add_ in populate() Cat () and add_ After Page (), the function will loop through the new Category and related Page objects, and display their names on the terminal.
def populate():
    # First, we'll create a dictionary list that contains the pages you want to add to each category.
    # Then, we will create a dictionary for our category. 
    # This may seem a bit confusing, but it allows us to traverse each data structure and add data to our model

    python_pages = [
        {'title': 'Official Python Tutorial', 'url':'http://docs.python.org/3/tutorial/'}, 
        {'title':'How to Think like a Computer Scientist', 'url':'http://www.greenteapress.com/thinkpython/'}, 
        {'title':'Learn Python in 10 Minutes', 'url':'http://www.korokithakis.net/tutorials/python/'} 
    ]

    django_pages = [
        {'title':'Official Django Tutorial', 'url':'https://docs.djangoproject.com/en/2.1/intro/tutorial01/'}, 
        {'title':'Django Rocks', 'url':'http://www.djangorocks.com/'}, 
        {'title':'How to Tango with Django', 'url':'http://www.tangowithdjango.com/'} 
    ]

    other_pages = [
        {'title':'Bottle', 'url':'http://bottlepy.org/docs/dev/'}, 
        {'title':'Flask', 'url':'http://flask.pocoo.org'} 
    ]

    cats = {'Python': {'pages': python_pages},
            'Django': {'pages': django_pages}, 
            'Other Frameworks': {'pages': other_pages} }

    # If you want to add more categories or pages, add them to the dictionary above

    # The following code traverses the cats dictionary, then adds each category, and then adds all relevant pages for that category.
    for cat, cat_data in cats.items():
        c = add_cat(cat) 
        for p in cat_data['pages']:
            add_page(c, p['title'], p['url']) 
    
        # Print out the categories we have added.
        for c in Category.objects.all():
            for p in Page.objects.filter(category=c):
                print(f'- {c}: {p}') 

# Create a new page
def add_page(cat, title, url, views=0):
    p = Page.objects.get_or_create(category=cat, title=title)[0] 
    p.url=url 
    p.views=views 
    p.save() 
    return p 

# Create a new category
def add_cat(name):
    c = Category.objects.get_or_create(name=name)[0]
    c.save() 
    return c

# Start from here
# __ name__ == '__main__'  Allows Python modules to act as reusable modules or stand-alone Python scripts
# Therefore, the code in if will be executed only when the module runs as a separate Python script. The import module will not run this code; However, you can have full access to any class or function
if __name__ == '__main__':
    print('Starting Rango population script...') 
    populate()  

get_or_create() method: create a Model instance in the fill script. If the instance does not exist in the DB, create it; If it exists, it returns a reference to an instance of a specific Model
get_ or_ The create () method returns an (object, created) tuple. Object is a reference to a Model instance; Created is a boolean value. If a Model instance must be created, it returns True.
get_or_create()[0]: only return object reference

(3) Run the following code to run the fill script, and you will get the following output:

$ python populate_rango.py


(4) Restart the server and check whether there is data filling

7. Summary of setup model

(1) Configure DB = > tell Django the DB to be used, that is, in settings Configure DATABASES in py; You can also go to admin.com of the app Register any models in the PY module and then make them accessible through the web-based management interface

(2) Add Model
a. In App models Py file to create your new Model
b. If the management interface can access the new Model, update admin Py to include and register Model
c. Migration

$ python manage.py makemigrations <app_name>

d. Run the following code to update the changes in the database

$ python manage.py migrate

e. Create / edit population script for new Model

(3) Operations required to refresh DB:
a. If DB is running, stop Django server
b. For SQLite database, delete the sqlite3 file in your Django project directory
c. If you change the Model of the APP, you need to run the following code (< APP_name > is replaced by the name of the Django application (i.e. rango)):

$ python manage.py makemigrations <app_name>

If your model has not changed, skip this step.
d. Run the following command to create a new DB file (if you are running SQLite) and migrate the database tables to the database

$ python manage.py migrate

e. Use the following command to create a new administrator account

$ python manage.py createsuperuser

f. Run the fill script again to insert reliable test data into the new database

Keywords: Python Database Django

Added by shashiku on Tue, 22 Feb 2022 22:31:24 +0200