Basic introduction to

1. Introduction

Django, pronounced Djangos, is an open source Web development framework written in Python that follows an MVC design. Django’s main purpose: to develop database-driven websites quickly and easily.

Study website:

Official website: www.djangoproject.com/

Github source: github.com/django/djan…

Django 英 文 版 : yiyibooks.cn/xx/Django_1…

Characteristics of 2.

  • Heavyweight framework

    In contrast to the Flask framework, Django native provides a multitude of functional components that make development easier and faster.

    • Provides project management automation script tools

    • Database ORM support Object Relational Mapping

    • The template

    • The form

    • Admin Manage site

    • File management

    • Certification authority

    • The session mechanism

    • The cache

  • MVT mode

    • M is Model, which has the same function as M in MVC. It is responsible for interaction with database and data processing.
    • V stands for View, which has the same function as C in MVC. It receives requests, performs business processing, and returns responses.
    • T is fully spelled as Template, which has the same function as V in MVC and is responsible for encapsulating and constructing the HTML to be returned.

3. Environment construction

  • Environment to prepare
    • python3.x
    • Django 3.0.4
    • Pycharm pro (Pro allows you to add some interface controls to the Django framework; community requires you to use the command line)
      • Reference other people’s pro break (harmony) solution tutorial: www.cnblogs.com/sillycuckoo…
  • Install djangoPIP install django = = 3.0.4

4. Create projects

  • Select the Django framework + Virtual Environment

  • Specify the Python Interpreter to run with your Project Perference->Project Interpreter-> select python.exe in a virtual environment

  • Files in the project

    • Outermost :django_project: the container for the project, you can name it whatever you want.
    • Manage.py: a command line tool that lets you manage Django projects in a variety of ways.
    • Django_project /init.py: an empty file that tells Python that the directory should be considered a Python package.
    • Django_project /settings.py: Configuration file for your Django project.
    • Django_project /urls.py: The URL declaration for your Django project, like the “directory” for your site.
    • Django_project /wsgi.py: Act as an entry point for your project to run on a WSGi-compatible Web server.
  • Start Command Configuration

  • If you access 127.0.0.1:8000, the environment is successfully set up

5. Settings. py Configuration file

  • App Path Configuration

    INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app1.apps.App1Config', 'app1' = 'app1'Copy the code
  • Database Configuration

    # if you are using the django's default sqlite3 database does not need to change the DATABASES = {' default ': {' ENGINE' : 'the django. Db. Backends. Sqlite3', 'NAME' : O.path. join(BASE_DIR, 'db.sqlite3'),}} DATABASES = {'default': {'ENGINE': 'django.db.backends.mysql', 'NAME': 'blog', 'username ',' username ', 'PASSWORD': ", # your database password 'HOST': ", # your database HOST, left blank Default localhost 'PORT': '3306', # your database PORT}}Copy the code
  • Static file directory

    Static _url = '/static/' static files_dirs =[os.path.join(BASE_DIR, "static"),Copy the code
  • The middleware

    # Self-written middleware, For example in the project folder md md. Py files of the M1 and M2 two MIDDLEWARE MIDDLEWARE = [' django. MIDDLEWARE. Security. SecurityMiddleware ', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', Md.md.m1 ', 'md.md.m2 ',] # pay attention to the middleware you write, the configuration should be written in the back of the systemCopy the code
  • Configuration of session storage

    Django supports sessions by default, and stores Session data in a database by default, namely, the Django_session table. # configuration Settings. Py SESSION_ENGINE = 'django. Contrib. Sessions. Backends. Db' # engine SESSION_COOKIE_NAME = "sessionid" # (the default) The key of the Session cookie when it is saved in the browser, namely: Sessionid = random string (default) SESSION_COOKIE_PATH = "/" # cookie save path of Session (default) SESSION_COOKIE_DOMAIN = None # Session cookie saved domain name (default) SESSION_COOKIE_SECURE = False # Whether Https transfer cookie (default) SESSION_COOKIE_HTTPONLY = True # SESSION_COOKIE_AGE = 1209600 # Session cookie expiration date (2 weeks) (default) SESSION_EXPIRE_AT_BROWSER_CLOSE SESSION_SAVE_EVERY_REQUEST = False SESSION_CACHE_ALIAS = 'default' SESSION_CACHE_ALIAS = 'default' # Use the cache alias, set this to the redis database configuration alias defaultCopy the code
  • Cache configuration

    • Memory cache configuration

      # configuration cache CACHES = {' default ': {' BACKEND' : 'django. Core. Cache. Backends. Memcached. MemcachedCache', 'the LOCATION: 'unix:/tmp/memcached.sock', 'KEY_PREFIX': 'lcfcn', 'TIMEOUT': None } }Copy the code
    • File cache Configuration

      CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', 'LOCATION': '/var/tmp/django_cache', # file path}}Copy the code
    • Database cache configuration

      CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.db.DatabaseCache', 'LOCATION': 'my_cache_table', 'my_cache_table',}}Copy the code

      After configuration, execute the following statement in CMD to create the cache table

      python manage.py createcachetable

    • Redis cache configuration

      CACHES = {# Configure cache data as redis "default": {"BACKEND": "django_redis.cache.RedisCache", "LOCATION": "Redis: / / 127.0.0.1:6379", "OPTIONS" : {" CLIENT_CLASS ":" django_redis. Client. DefaultClient ", "PASSWORD" : "12345"}}}Copy the code
    • There are several additional parameters in the CACHES setting:

      • TIMEOUT: cache TIMEOUT period. The default value is 300 seconds. You can set this parameter to None.

      • OPTIONS: Locmem, Filesystem, and Database caching systems with their own culling strategies have the following parameters:

      • MAX_ENTRIES: Maximum number of entries in the cache, above which old entries will be deleted. Default is 300.

      • CULL_FREQUENCY: The rate of accepted entries when MAX_ENTRIES are reached. The actual ratio is 1/cull_frequency, so setting it to 2 will remove half of the cache when max_entries are reached, and setting it to 0 will remove the cache when max_entries are reached. The default value is 3.

      • KEY_PREFIX: a string that is automatically included in the cache key.

      • VERSION: VERSION number used when the cache key value is generated.

      • KEY_FUNCTION: the method used for the final generation of the key value.

6. Django common commands

  • Create a project

    django-admin startproject project_name

  • A new app

    CD Project root directory

    python manage.py startapp app_name

  • Create database tables or change database tables or fields

    Generates migration script Python manage.py Makemigrations

    Execute the python manage.py migrate script

  • Using the development server

    The development server is used during development. It automatically restarts after modifying the code, facilitating debugging and development. However, due to performance problems, you are advised to use it only for testing, not for production.

    python manage.py runserver

    When a message is displayed indicating that a port is occupied, you can use another port:

    python manage.py runserver 8001

    Monitor all available IP addresses of the machine (the computer may have multiple internal IP addresses or multiple external IP addresses)

    Python manage. Py runserver then executes 0.0.0.0:8000

    If it is an Internet or LAN computer, you can view the development server on another computer

    Access the corresponding IP address plus port, such as http://172.16.20.2:8000

  • Clearing the database

    python manage.py flush

    This command asks for yes or no, and selecting yes clears out all data except for the empty table.

  • Creating a Super Administrator

    python manage.py createsuperuser

    Enter the user name and password as prompted. The email can be left blank. The user name and password are mandatory

    To change a user password, run the following command:

    python manage.py changepassword username

  • Export data Import data

    python manage.py dumpdata appname > appname.json

    python manage.py loaddata appname.json

  • Django project environment terminal

    python manage.py shell

    If you install bPython or ipython, their interfaces will be automatically used. It is recommended to install BPython.

    The difference between this command and running Python or bpython directly into the shell is that you can call the API in the models.py of the current project from inside the shell, and there are some handy little tests for manipulating data.

  • Database command line

python manage.py dbshell

Django automatically accesses the database you set up in settings.py, or if it's MySQL or postgreSQL, it asks for the database user password. SQL statements from the database can be executed at this terminal. If you are familiar with SQL, you may prefer this approach.Copy the code
  • Reverse generation model

    python manage.py inspectdb

  • More orders

    python manage.py

    You can see a detailed list, which is especially useful when you forget child names.

view

View functions

  • introduce

    A view function, or view for short, is a simple Python function that accepts a Web request and returns a Web response. The response can be the HTML content of a web page, a redirect, a 404 error, an XML document, or an image, anything. No matter what logic the view itself contains, the response is returned. It doesn’t matter where the code is written, as long as it’s in your Python directory. There is nothing more to ask for — “nothing magical”, so to speak. To put the code somewhere, the convention is to place the view in a file called views.py in the project or application directory.

    View function:

    Must contain two objects:

    • Request —-> All information related to the user’s request (object)

    • Httpresponse—-> Response string

  • Simple view demo

    from django.http import HttpResponse The HttpResponse class is imported
    
    We define the hello_world function. It's the view function.
    Each view function takes an HttpRequest object as its first argument and is commonly referred to as request.
    def helloworld(request) :
        return HttpResponse("helloworld! Hello, beta tester!")
    Copy the code
  • Configure the routing

    The main route, the urls.py under the project

    from django.contrib import admin
    from django.urls import path, include
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('test/',include('views_demo.urls')))Copy the code

    Subroutes, which are urls. Py under the app

    from django.urls import path
    from views_demo import views
    
    urlpatterns = [
        path('helloworld/',views.helloworld),
    ]
    Copy the code
  • Follow the routing access example

    Shows the return of the helloWorld function defined in views.py

2. Request and response

View functions around two objects: HttpResponse and HttpRequest

  • HttpRequest

    Request —-> Request information

    Request. Method property # GET the HTTP method used in the request (POST/GET) request. Body # Request #GET request data (dictionary-like object) in the url in the request header? Request.POST # POST the value of the requested data (dictionary-like object) in the request body. Keys and values are strings. Request. FILES: dictionary-like object containing all uploaded FILES; Each Key in FILES is the value of the name attribute in the <input type="file" name=""/> tag. Each value in FILES is also a standard Python dictionary object, containing the following three Keys: -filename: indicates the upload filename, expressed as a string. -content_type: indicates the Content of the uploaded file. Type - Content: indicates the original Content of the uploaded file. Is a django contrib. Auth. Models. The User object, represent the current logged in User. If access to user is currently not login, the user will be initialized to django. Contrib. Auth. Models. AnonymousUser instance. You can tell if a user is authenticated by using the is_authenticated() method: if req.user.is_authenticated(); Request. session: a unique read-write property that represents the dictionary object of the current session; Request.get.GET ('name') gets the value of name in a GET request. If a key pair should have multiple values, use getList instead of GET, as in: Request. POST. Getlist (" hobby ") request url: http://127.0.0.1:8000/index.html/23? a=1 request.path : Request path request.path :/index.html/23 request.get_full_path() request.get_full_path() :/index.html/23? a=1Copy the code

    Try printing it yourself in a view function, which you can see on the console:

    def helloworld(request): print(request.path) print(request.GET) print(request.body) return HttpResponse("helloworld! Hello, beta tester!" )Copy the code
  • HttpResponse

    HttpResponse—-> Response string

    For HttpRequest request objects, Django creates them automatically, but HttpResponse response objects must be created ourselves. Each view request handler must return an HttpResponse response object. The HttpResponse class is in Django.http.HttpResponse.

    Common attributes:

    Content: The returned content. Response = HttpResponse() Response.content = 'Fruitsoftware' Return Response status_code: the returned HTTP response status code content_type: the MIME type of the returned dataCopy the code

    Common methods:

    Set_cookie: used to set cookie information delete_cookie: used to delete cookie information. Write: HttpResponse is a file-like object that can be used to write data to the content.Copy the code
  • JsonResponse object

    Def test_redirect(request): Return JsonResponse([{"code":0000," MSG ":' success '}],safe=False) JsonResponse({"code":0000," MSG ":' success '},safe=FalseCopy the code
  • Other common response functions and objects

    • Render function (front and back end separate development, do not need to master, understand it)

      Renders the specified page and returns it to the browser

      Render (request, template_name, context [])

      Combine a given template with a given context dictionary and return a rendered HttpResponse object.

    • Redirect function

      The parameters can be:

      A model: the get_absolute_URL () function of the model will be called to a view, which can take arguments: urlresolvers. Reverse will be used to reverse resolve the name to an absolute or relative URL, leaving it unchanged as the redirection location.

      By default, a temporary redirect is returned; Passing permanent=True returns a permanent redirect.

3. The class view

> A view defined in the form of a function is a function view. View functions are easy to understand, but when the path of a view function provides support for different HTTP request modes (GET, POST, DELETE, PUT), different business logic needs to be written in a function, resulting in low readability and reusability of the code. So, let's fix this by introducing class views.Copy the code
  • Class views are not used

    Def register(request): """ """ """ Return render(request, 'register.html') else: # render(request, 'register.html')Copy the code
  • Use the class view example

    Class DefineClassview(View): """ "def get(self, request): Return HttpResponse('GET request ') def post(self, request): "" return HttpResponse('POST request business logic ') def put(self, request): passCopy the code
  • The use of class views

    • To define a class View, you need to inherit the View from the parent class provided by Django

    • The import

      • from django.views.generic import View
    • Example: views. Py

      From django. HTTP import HttpResponse from django.views import View # import View class ViewDemo(View): def get(self): Return HttpResponse("get method is called ") def post("post method is called ") def put(self,request): return HttpResponse("get method is called ") Return HttpResponse("put method is called ") def delete(self,request): return HttpResponse("put method is called ")Copy the code
    • When configuring a route, you need to register the addition using the as_view() method of the class view

      Urlpatterns = [path(", view.viewdemo.as_view ())),# use as_view() to register class views as views]Copy the code
    • Remove middleware that disables cross-domain access

      If the interface returns 403 Forbidden, comment out middleware that disables cross-domain access in settings.py

routing

1. Single route

A path corresponds to a view function or a view class

Urlpatterns = [path('hello/',view.hello_world), path(", view.viewdemo.as_view ())),# register class views as views using the as_view() method]Copy the code

2. Routes-based routes

When accessing an interface, the interface address must end with a /. We can solve this problem with regular expression based routing.

Note:

  • Regular expression based routing must use re_path instead of the path we used before

  • The regular expression string starts with the letter “R”. It tells Python that this is a raw string and that it does not need to handle the backslash (escape character) inside it (not needed after version 2.0).

    Urlpatterns = [re_path(r'^hello.?$', view.viewdemo.as_view ())),#.? Represents 0 to 1 arbitrary characters, so we can omit the last/when accessing addresses.Copy the code

3. Route parameters are transmitted

  • Routing parameter passing changes the way it’s written a bit in Django

    Urlpatterns = [path("args/< PK >/",view.args_demo),# default matches string]Copy the code
  • The view function parameter list requires variables to receive URL parameters, and the parameters in the view are consistent with the above keywords

    Def args_demo(request,pk): def args_demo(request,pk): return HttpResponse("pk: {}".format(pk))Copy the code
  • Note:

    • To capture a value in a URL, Angle brackets are used
    • You can convert the captured value to a specified type, such as int in the example. By default, the captured result is saved as a string without the special character /;
  • You can also write it as a regular expression

    Urlpatterns = [re_path (r "^ the args/(? P < pk > [a zA - Z] +).? $", the args_demo) # the regular expression method and] # (? # [a-za-z]+ = 1 or more letters, depending on your regular expression # (? P<pk>[a-za-z]+Copy the code
  • Url parameter converter

Urlpatterns = [path("args/<int:pk>/",view.args_demo),# matches parameters of int type]

  • Passing multiple parameters
    path("args/<int:page>/<int:size>/",view.args_demo)
    Copy the code
  • View functions also need to declare multiple parameters to receive
    Def args_demo(request,page,size):# return HttpResponse("page: {},size: {}): {}".format(page,size))Copy the code
  • Parameter pass default values
    path("args/<int:page>/<int:size>/",view.args_demo,{"page":1,"size":5})
    Copy the code

4. Route distribution

Route distribution refers to how to forward a request level by level to the corresponding program for processing. In Django, this usually means distributing from the main app to child apps

  • Creating a Child application

    python manage.py startapp app01

  • Settings. py introduces the app you just created

  • Create child routing files in child applications

  • Write a view and route information in the sub-application to facilitate route distribution

views.py

from django.http import HttpResponse
from django.shortcuts import render

# Create your views here.

def hello_world(request):

    return HttpResponse('hello world')
Copy the code

urls.py

from django.urls import path, re_path

from . import views

urlpatterns = [
    re_path(r"^hello.?$",views.hello_world),
]
Copy the code
  • Use include to distribute routes
from django.urls import path, re_path, Include from django_project import View urlpatterns = [Path ("v01/",include("app01.urls"))]Copy the code
  • After restarting the service, the browser is accessed

5. Url reverse lookup and namespaces

In practice, some views are redirected to other views via the url redirect. However, if the URL address is changed, url redirection fails. To solve this problem, we introduce the concept of named routes and namespaces

ORM

  • The ORM concept

Object Relational Mapping (ORM) pattern is a technique to solve the mismatch between object-oriented and Relational databases. Simply put, ORM automatically persists an object in a program to a relational database using metadata that describes the mapping between the object and the database. ORM acts as a bridge between the business logic layer and the database layer

  • The ORM origin

Let’s start with O/R. The letter O comes from Object, and the letter R comes from Relational. Almost all software development processes involve objects and relational databases. At the user level and at the business logic level, we are object-oriented. When the object’s information changes, we need to store the object’s information in a relational database. Following the previous approach to development would result in programmers inserting SQL statements into their business logic code to add, read, modify, and delete data, often with very similar or duplicate code

  • The ORM advantage

The main problem ORM addresses is the mapping of objects and relationships. It typically maps a class to a table, with each instance of the class corresponding to a record in the table, and each attribute of the class corresponding to each field in the table. ORM provides a mapping to the database, and instead of writing SQL code directly, you can manipulate the data by manipulating objects. Allowing software developers to focus on processing business logic improves development efficiency.

  • The ORM disadvantage

The disadvantage of ORM is that it may sacrifice the execution efficiency of the program to some extent. ORM operations are limited, that is, ORM defined operations can be completed, some complex query operations are not completed. ORM with more SQL statements will not write, relational database related skills degradation…

  • The ORM summary

ORM is just a tool, and tools do solve some repetitive, simple tasks. There is no denying it. But we can’t expect one tool to solve all problems once and for all. Some special problems require special treatment. However, there should be very few cases that require special treatment throughout the software development process, otherwise the so-called tool will lose its purpose.

  • Mapping between ORM and DB

ORM object – oriented and relational database mapping, through the operation of the object database data, does not support the operation of the library, only the operation of the table relationship: class -> table object -> data row attributes -> field

In Django, the Model is a single, unambiguous source of information for your data. It contains the important fields and behaviors of the data you store. Typically, a model maps to a database table.

  • Basic Information:

Each Model is a Python class that is a subclass of Django.db.models.Model. Each attribute of the model represents a database field.

To sum up, Django provides you with an automatically generated database access API. Check out the official documentation

1. The installation of mysql

  • Install historical version 5.7
  • Reference: www.jianshu.com/p/56e965f90… Mysql > Install mysql

2. Django connects to the configuration database

  • Create a new database in mysql

  • Install the msyql client

    PIP install mysqlclient = = 1.4.6

  • Configures database link information in settings.py

    The DATABASES = {' default ': {' ENGINE' : 'the django. Db. Backends. Mysql', 'HOST' : '127.0.0.1, # database HOST' PORT ': 3306, # database port 'USER': 'root', # database username 'PASSWORD': 'root', # database username 'NAME': 'test' # database NAME}}Copy the code
  • Check whether the configuration is successful

    • Run python manage.py dbshell in pycharm Terminal
    • If the mysql virtual terminal is displayed, the configuration is successful

3. ORM table model

Define the model

In Django, all models must inherit from Django.db. models import Model. The field types must use the field types defined in the Models module

from django.db import models class Student(models.Model): CharField specifies the maximum length of a field. Max_length specifies the maximum length of a field. Non-null constraint (null=False, default, writable), primary key constraint (primary_key=True), unique constraint (unique=True), nullable (null=True), ForeignKey constraint (specified by models.foreignkey ()) # # choices=((0, 'male '), (1,' female ')). This field only has two values: 0, 1. DateTimeField this field is the date type. # auto_now_add=True Records the current time each time data is added. # auto_now=True Records the current time each time data is saved. S_name = models.CharField(max_length=64,help_text=" student name ") s_sex = models.IntegerField(choices=(0, 'male '), (1, 'female '), help_text=" gender ") s_phone = models.CharField(max_length=11, Help_text =" phone number ") create_time = models.datetimefield (auto_now_add=True) update_time = models.datetimefield (auto_now=True) Class Meta: db_table = 'student' # db_table = 'student' #Copy the code

The following figure shows the relationship between mysql database fields and types defined in Models

Common attributes in the model

Django provides some special properties
EmailField (CharField) : - The value is a string. -e_mail = models.EmailField(max_length=255, unique=True) IPAddressField(Field) GenericIPAddressField(Field) - Django Admin and ModelForm provide IPV4 and Ipv6 validation - parameters: Protocol: used to specify Ipv4 or Ipv6, 'both'," Ipv4 "," Ipv6 "unpack_ipv4. If True, enter :: FFFF :192.0.2.1. Protocol ="both" URLField(CharField) -string, Django Admin and ModelForm provide validation URL SlugField(CharField) -string, Django Admin and ModelForm validation support letters, Numbers, underscores, connector (minus) CommaSeparatedIntegerField (CharField) - string type, UUIDField(Field) - string type, Django Admin and ModelForm provide UUID format validation FilePathField(Field) - string, Django Admin and ModelForm provide the ability to read files in folders. Path, folder path match=None, regular match recursive=False, allow_files=True, allow_folders=False, allow_folders=False, Allows folder FileField(Field) - string, path saved in database, file uploaded to specified directory - Parameters: Upload_to = "" upload file save the path storage = None storage component, the default django.. The core files. Storage. FileSystemStorage ImageField (FileField) - string, Path saved in database, file uploaded to specified directory - Parameter: Upload_to = "" Storage = None The default django) core) files. Storage. FileSystemStorage width_field = None, Height of uploaded image Saved Database field name (string) Height_field =None Width of uploaded image Saved database field name (string)Copy the code
Custom fields (understand)

Example: We noticed that there is no fixed length string type, but the mobile phone number field is usually a fixed length string of 11 bits, so we need to customize some field types

from django.db import models # Create your models here. class PhoneField(models.Field): Def __init__(self, max_length, *args, **kwargs): self.max_length = max_length super(PhoneField, self).__init__(max_length=max_length, *args, **kwargs) def db_type(self, Return 'char(%s)' % self.max_lengthCopy the code
The common parameter of Field

Meta configuration in the model:

For some model-level configurations. We can define a class in the model called Meta. You then add some class attributes to this class to control what the model does.

For example, we want to use our own table name for database mapping instead of using the name of the model. Add a db_Table attribute to the Meta class. Example code is as follows:

class Book(models.Model):
    name = models.CharField(max_length=20,null=False)
    desc = models.CharField(max_length=100,name='description',db_column="description1")

    class Meta:
        db_table = 'book_model'
Copy the code

Foreign keys and table relationships

4. ORM model migration

Generate migration script
  • python manage.py makemigrations

  • A 0001_initial.py file is generated in the migrations folder under model_demo as follows:

    from django.db import migrations, models class Migration(migrations.Migration): initial = True dependencies = [ ] operations = [ migrations.CreateModel( name='Student', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('s_name', Models. CharField (help_text = 'student's name, max_length = 64)), (' s_sex' models. IntegerField (choices = [(0, 'male'), (1, 'female')]. Help_text =' gender '), ('s_phone', models.CharField(help_text=' phone', max_length=11)), ('create_time', models.DateTimeField(auto_now_add=True)), ('update_time', models.DateTimeField(auto_now=True)), ], options={ 'db_table': 'student', }, ), ]Copy the code

    There is a new id field that django automatically generates for all tables, so you don’t have to define it.

    The database does not have this table when the migration script is generated.

Perform specimen migration and create new tables in the database
  • python manage.py migrate

You can add the name of the app after the command because you did something else earlier and just wanted to execute the migration script under model_demo.

The student table is created in the database, and the django_migrations table stores the Django migration records.

We can see that the constraints on these fields are the same as those we defined:

Migration command description
  • Names, Hoisting Generate migration scripts for the model. The app in which the model resides must be in INSTALLED_APPS in settings.py. This command has the following common options:

    • App_label: This can be followed by one or more apps, for which only the migration script will be generated. If there is no app_label, then the models under all apps in INSTALLED_APPS are checked and a responsive migration script is generated for each app.

    • -name: specifies a name for the migration script.

    • -empty: Generates an empty migration script. If you want to write your own migration script, you can use this command to implement an empty file and then write the migration script in the file yourself.

  • Migrate: Migrate a newly generated migration script. Map to the database. Create a new table or modify the structure of the table. Here are some common options:

    • App_label: Maps migration scripts under an app to the database. If not specified, all models under the APP in INSTALLED_APPS are mapped to the database.

    App_label MigrationName: Maps a migration file named in an app to the database.

    • – Fake: You can add the specified migration script name to the database. However, the migration script is not converted into SQL statements that modify the tables in the database.
    • – Fake-initial: records the version number of the first generated migration file in the database. The migration script is not actually executed.
  • Showmigrations: displays migration files in an app. If there is no app behind, then all migration files in INSTALLED_APPS will be viewed.

  • Sqlmigrate: View the SQL statements that can be converted when a migrated file is mapped to a database.

5. Abstract creates the model parent class

At the time of creating the model, there are a lot of fields are common existing in the model, such as createtime, updatetime, mark, etc., these fields we need to create duplicates in each model, which creates a waste of effort, we can create a common model to the parent class, subclass to integrate the parent class, So we don’t have to write these fields again

class PublicModel(models.Model): Createtime = models.DateTimeField(auto_now_add=True,verbose_name=" created date ") updateTime = Models.DateTimeField(auto_now=True,verbose_name = 'DateTimeField ') status = Models.IntegerField(verbose_name =' status ') Class Meta: Abstract =True # This property must be specified in the parent class, otherwise the class will be created in the database. Createtime,update,status class Student(PublicModel); CharField(max_length=64,help_text=" student name ") s_sex = models.IntegerField(choices=((0, 'male '), (1,' female ')), Help_text =" gender ") s_phone = models.CharField(max_length=11, help_text=" phone number ") Class Meta: db_table = 'student'Copy the code
  • The model is modified and remigrated
    • Delete the migration scripts in the Migrations folder
    • Delete migration records from the django_migrations table
    • Delete the student table
    • Rebuild the migration script
    • Executing the migration script

6. The ORM operation

ORM operation preparations
  • Use this model for subsequent ORM operation exercises

    class Student(models.Model): CharField(max_length=64,help_text=" student name ") s_sex = models.IntegerField(choices=((0, 'male '), (1,' female ')), Help_text =" gender ") s_phone = models.CharField(max_length=11, Help_text =" phone number ") create_time = models.datetimefield (auto_now_add=True) update_time = models.datetimefield (auto_now=True)  class Meta: db_table = 'student'Copy the code
  • Go to Django’s virtual terminal

  • Import the model class to operate on

The new data
  • Insert single data -save

    S = Student(s = name,s_sex=0,s_phone='18103909786') save()Copy the code

    A new record was added to the database:

  • To insert a single data -create

    Use model objects to manipulate databases

    Student.objects. Create (s_name,s_sex,s_phone='15855586589')Copy the code

    A new record was added to the database:

  • To insert multiple pieces of data in batches -bulk_create

    S1 = Student(s_name,s_sex=0,s_phone='18103909782') s2 = Student(s_name,s_sex=0,s_phone='18103909783') s3 = Student_list = [s1,s2,s3] Student.objects. Bulk_create (student_list) student_list = [s1,s2,s3]Copy the code

    More data has been added to the database:

To find the data

The search data is realized through the objects under the model

  • Find all data

    Use student.objects.all () as select * from Student

    As we can see from the above example, we use the student.objects.all () method to query all the data and return a list of querySets containing Student objects. Students [0] = Student; s_name = Student; s_sex = s_phone

Data filtering
  • Single condition filtration

    When looking for data, it is sometimes necessary to filter some data. Call the Objects filter method.

    SQL > select * from s_name (‘ luban no.7 ‘, ‘luban no.7’);

    The result of the search returns a QuerySet. The built-in QuerySet methods are values() and first().

    Values () displays detailed data, which is easier to read. First () displays the first data

  • Other Filter criteria (double underline query)

    S = student.objects.filter (s_name__contains=' king ') s[0]. S_name # select * from student.objects.filter (s_name__contains=' king ' s=Student.objects.filter(id__gt=2).values() sCopy the code

    Common symbols

  • The date filter

    USE_TZ = False in settings.py

    S = student.objects. filter(create_time__date='2020-07-05')Copy the code

  • Comparison of dates

    Import datetime date = datetime.datetime(2020,4,2) student = Student.objects.filter(create_time__gte=date)Copy the code
Other query methods
  • Get the query

    If one or more data is not obtained, an error is reported. The primary key is used for query.

    S = student.objects.get (pk=1)

  • exclude

    Exclude returns a list of QuerySet objects

    S = student.objects.exclude (pk=1)Copy the code

  • values

    The queried object is converted to a dictionary.

    S = student.objects.exclude (pk=1) The result is a list of objects of type QuerySet s.values('s_name','s_sex') # then use values() to determine the display field student.objects.values ('s_name','s_sex') # Query all data and determine display fieldsCopy the code

  • values_list()

    It is very similar to values() in that it returns a sequence of tuples, saving space relative to dictionaries.

    Student.objects.values_list('s_name','s_sex')
    Copy the code

  • first

    Take the first element. None of the elements returns None, and the first record is returned. Student.objects.exclude(pk=1)[0]; student.objects.exclude (pk=1)[0]

    Student.objects.exclude(pk=1).first()

  • last

    Take the last element. None of the elements returns None, and the last record is returned. And the first in the same way

    Student.objects.exclude(pk=1).last()
    Copy the code
  • exists

    Return True if QuerySet contains data, False otherwise

    Student.objects.filter(pk=1).exists()
    Copy the code
  • Nested query

    Select * from student where id=2 and gender = 1
    SELECT * from student where s_sex in (SELECT s_sex from student where id=2)
    Copy the code

    The ORM implementation:

    student=Student.objects.filter(pk=2)
    Student.objects.filter(s_sex=student[0].s_sex)
    Copy the code

  • F the query

    (Compare and process fields in your own single table)

    In all of the examples above, we constructed filters that simply compare the field value to a constant. What if we want to compare the values of two fields?

    From django.db.models import F student.objects. filter(update_time__gt=F("create_time"))Copy the code
Multi-condition query
  • Parallel relationship

    By default, filter is a juxtaposition, and comma division is a juxtaposition

    Objects.objects.filter (s_name= 0,s_sex=0)Copy the code

  • Q query

    To use Q query, import Q query module first

    from django.db.models import Q
    Copy the code
    • With &

      Stu = student.objects.filter (Q(s_sex=0) &q (s_sex=0))Copy the code

    • Or |

      Screening s_name = # 'ruban 7 or s_sex stu = = 1 Student. Objects. The filter (Q (s_name =' ruban 7) | Q (s_sex = 1))Copy the code

    • Non –

      stu=Student.objects.filter(~Q(s_sex=0))
      Copy the code

Data aggregation – Aggregate

SQL aggregate functions include Max (), min(), count(), avg(), sum().

To perform statistical operations on data using aggregate functions, you need to use the aggregate method, which returns a dictionary.

Aggregate generates statistics from the entire query result set.

  • Class to import aggregate functions

    from django.db.models import Avg, Sum, Max, Min, Count
    Copy the code
  • Usage: Filter first, then aggregate

  • Changing the field name

The sorting

Sorting usingorder_by()

# according to the id field positive sequence alignment, the default for the positive sequence, from small to large stu = Student. Objects. The filter (Q (s_name = 'ruban 7) | Q (s_sex = 0)). Order_by (" id ") # according to the id field arranged in reverse chronological order, Add a symbol stu = Student. Objects. The filter (Q (s_name = 'ruban 7) | Q (s_sex = 0)). Order_by (" id ")Copy the code
Data to heavy

Deduplication valuse(” deduplication field “). Distinct

Stu = student.objects.filter (s_sex=0).values("s_sex").distinct()Copy the code

paging

Paginator uses Django’s built-in Paginator to paginate data

  • Import pager

    from django.core.paginator import Paginator
    Copy the code
  • paging

    Paginator Import paginator # paginator the first parameter is the data to be pagined, P = Paginator(student.objects.all (),per_page=2) # get_page() specifies the number of pages for which the data is to be collected and returns a Page object. Print (p.ge_page (1).object_list)Copy the code

    When no data is retrieved from the number of pages, the last page of data is returned.

    P.page (1).has_next()Copy the code

    Page (1).has_previous()Copy the code

    Some other paging operations:

grouping
  • Grouping in SQ

    select s_sex,count(*) from student group by s_sex;
    Copy the code

    SQL groups have syntax conventions. The fields displayed can only be grouped fields and aggregate functions.

    In ORM, we also focus on display fields and grouping fields

  • The grouping of ORM

    Student.objects.all().values('s_sex').annotate(Count('id')).values('s_sex','id__count')
    Copy the code

    Values (‘s_sex’) is an annotate(Count(‘id’)), and values(‘s_sex’,’id__count’) is an annotate(‘id’). Count (‘id’), the return field is id__count, so here shows the field to write id__count

    So, it can also be written like this: count= count (‘id’)

    Student.objects.all().values('s_sex').annotate(count=Count('id')).values('s_sex','count')
    Copy the code

  • How to implement having

    Using filter after Annotate is equivalent to having

    Student.objects.all().values('s_sex').annotate(count=Count('id')).filter(count=1).values('s_sex')
    Copy the code

Modify the data

The data structures queried by GET and filter are different. The result queried by GET is an object, while the result queried by filter and exclude is a query set. Their modification operations are different.

  • An operation to modify an object

    Stu = student.objects.get (id=3) # stu= student.objects.get (id=3) # stu= student.objects.get (id=3) # stu= student.objects.get (id=3) # stu= 1 The database value has not changed stu.save() # use.save() to trigger the operation on the databaseCopy the code
  • Modify operations on query sets

    Update (s_phone='13800000000') # update(s_phone='13800000000') # update(s_phone='13800000000') # update(s_phone='13800000000') Update (s_phone='13800000000',s_name=' wang2 ')Copy the code

Delete the data

After you find the data, you can delete it. Deleting data is as simple as calling the delete method on this object.

stu = Student.objects.get(id='6')
stu.delete()
Copy the code
  • Physical delete & logical delete

Transactions and rollback
  • What are transactions and rollback

    Transaction: A collection of multiple data logic operations

    Rollback: Return to the initial state when an operation in multiple logic fails

    The atomicity of a transaction requires that the transaction either complete completely or not complete at all, and it is impossible to stagnate in some intermediate state

  • When do transactions need to be used

    Modifying multiple ORM models requires the use of transactions and rollback operations

    Strict consistency of results (all success or all failure)

  • How do you use transactions in Django

    • Automatic transaction commit and rollback
      Db import transaction from Django. db import transaction from Django. db import transaction test(request): Stu = student.objects.get (id=0) # select student.objects.filter (id=1). Update (s_sex=1) Stu.s_sex =1 stu.save() student.objects.filter (id=2).update(s_sex=1)# return HttpResponse("ok") def Test (request): # Implement automatic transaction commit and rollback with transaction.atomic(): Stu = student.objects.get (id=1). Update (s_sex=1) # stu = student.objects.get (id=0) # Stu.s_sex =1 stu.save() student.objects.filter (id=2). Update (s_sex=1)# return HttpResponse("ok")Copy the code
    • Manual transaction commit and rollback
      Def test(request): Transaction.set_autocommit (False)# Disable Django autocommit student.objects.get (id=1). Update (s_sex=1) # Stu = student.objects.get (id=0) # stu = student.objects.get (id=0) Stu.s_sex =1 stu.save() student.objects.filter (id=2).update(s_sex=1) Transaction. Rollback () # return HttpResponse(" OK ")Copy the code

7. ORM multiple table association

correlation
  • One to one

    student <—-> student_info

  • For one more

    score ——–> student

    score ——–> course

    course ——–> teacher

  • Many to many

    student <———————-> course

Association model creation
  • One-to-one models. OneToOneField ()

    Relational relationships are placed in tables that are used more frequently

  • Many-to-one models. ForeignKey ()

    The correlation is placed in the “many” table

  • Many-to-many models. ManyToManyField ()

    Associations are placed in tables that are used more frequently

  • Cascading delete on_delete from relational tables

Code sample

models.py

from django.db import models


# Create your models here.

# students table
class Stu(models.Model) :
    s_name = models.CharField('Student name', max_length=64, null=False, help_text='Student name')
    s_sex = models.IntegerField('gender', max_length=1, choices=((0.'male'), (1.'woman')), help_text='gender')
    s_age = models.PositiveIntegerField('age', null=False, default=0, help_text='age')
    s_dept = models.CharField("Professional", max_length=64, null=False, help_text="Professional")
    # One-to-one relationships, with models.onetoonefield (), are placed in tables that are used more frequently
    "" models.oneToonefield () takes three parameters: To_field: sets the table field (class attribute) to be associated with. On_delete: Sets the value of s_id when the associated field is deleted. The usual setting is models.CASCADE, indicating that when the associated field is deleted, """
    "" "related_name: In the forward query, s_id is used to query data in the student_info table. In the reverse query, related_name is used to query data in the student table.
    # db_column Specifies the table column name
    si_id = models.OneToOneField(to='StudentInfo', to_field="id", on_delete=models.CASCADE, db_column='si_id',
                                 related_name="stu_stu_info")
    
    Db_table is the name for an intermediate table that is automatically generated in many-to-many relationships
    course = models.ManyToManyField(to="Course", db_table="stu_course", related_name="course_student")

    class Meta:
        db_table = 'stu'

# Student information sheet
class StudentInfo(models.Model) :
    s_card = models.CharField("Id Number", max_length=18, null=False, unique=True)
    s_phone = models.CharField(max_length=11, null=False, unique=True, help_text="Mobile phone Number")
    s_addr = models.CharField("Home address", max_length=128, help_text="Home address")

    class Meta:
        db_table = "student_info"

# the curriculum
class Course(models.Model) :
    c_name = models.CharField('Course Name',max_length=64,null=False,help_text="Course Name")
    t_id = models.ForeignKey(to="Teacher",to_field="id",on_delete=models.CASCADE,related_name='teacher_course',db_column='t_id',help_text="Teacher Number")

    class Meta:
        db_table="course"

The result for #
class Score(models.Model) :
    s_id = models.ForeignKey(to="Stu", to_field="id", on_delete=models.CASCADE, related_name='stu_score',
                             db_column='s_id', help_text="Student Number")
    c_id = models.ForeignKey(to="Course", to_field="id", on_delete=models.CASCADE, related_name='course_score',
                             db_column='c_id', help_text="Student Number")
    score = models.PositiveIntegerField("Performance",null=False,default=0,help_text="Performance")

    class Meta:
        db_table = "score"

# the teacher table
class Teacher(models.Model) :
    t_name = models.CharField("Name of teacher", max_length=64,null=False,help_text="Name of teacher")

    class Meta:
        db_table = "teacher"
Copy the code

Data migration:

python manage.py makemigrations
python manage.py migrate multi_table
Copy the code
Association model operation

Add, delete and change, are single table operation, only query involves multiple tables, we will mainly talk about the next query of multiple table operation

  • Data preparation

    -- Data preparation SQL
    insert into `student_info` (`id`, `s_card`, `s_phone`, `s_addr`) values('1'.'410422200205061358'.'18103909786'.'Lushan County, Henan Province');
    insert into `student_info` (`id`, `s_card`, `s_phone`, `s_addr`) values('2'.'310112199003074772'.'13853444534'.'Minhang District, Shanghai');
    insert into `student_info` (`id`, `s_card`, `s_phone`, `s_addr`) values('3'.'31011520020907641X'.'15520979867'.'Pudong New Area, Shanghai');
    
    insert into `stu` (`id`, `s_name`, `s_sex`, `s_age`, `s_dept`, `si_id`) values('2'.'Xue Xiaolei'.'0'.'18'.'Computer Science'.'1');
    insert into `stu` (`id`, `s_name`, `s_sex`, `s_age`, `s_dept`, `si_id`) values('3'.King's Sledgehammer.'1'.'30'.'Biological Science'.'2');
    insert into `stu` (`id`, `s_name`, `s_sex`, `s_age`, `s_dept`, `si_id`) values('4'.'Xue Dalei'.'0'.'18'.Foreign trade Finance.'3');
    
    insert into `teacher` (`id`, `t_name`) values('1'.'Joe');
    insert into `teacher` (`id`, `t_name`) values('2'.'bill');
    insert into `teacher` (`id`, `t_name`) values('3'.'Cathy');
    
    insert into `course` (`id`, `c_name`, `t_id`) values('1'.'mathematics'.'1');
    insert into `course` (`id`, `c_name`, `t_id`) values('2'.'Chinese'.'2');
    insert into `course` (`id`, `c_name`, `t_id`) values('3'.'English'.'3');
    
    insert into `score` (`id`, `score`, `c_id`, `s_id`) values('1'.'80'.'1'.'2');
    insert into `score` (`id`, `score`, `c_id`, `s_id`) values('2'.'90'.'2'.'2');
    insert into `score` (`id`, `score`, `c_id`, `s_id`) values('3'.'85'.'3'.'2');
    insert into `score` (`id`, `score`, `c_id`, `s_id`) values('4'.'60'.'1'.'3');
    insert into `score` (`id`, `score`, `c_id`, `s_id`) values('5'.'55'.'2'.'3');
    insert into `score` (`id`, `score`, `c_id`, `s_id`) values('6'.'70'.'3'.'3');
    insert into `score` (`id`, `score`, `c_id`, `s_id`) values('7'.'30'.'1'.'4');
    insert into `score` (`id`, `score`, `c_id`, `s_id`) values('8'.'50'.'2'.'4');
    Copy the code

    Tips: You need to refresh the Python Console when the model changes

  • The new data

    The student table and the middle table stu_course are many-to-many. The middle table is automatically generated by Django and has no data. Intermediate table data, can only be generated from one table to another table data, we generated from the STU table stu_course table data.

    Stu = stu.objects.filter (s_name=' objects.filter ').first() Add (1,2,3) # stu.course.add(1,2,3) # stu_id= 3 course_id =2; Stu.objects.get(pk=3).course.add(2,3) stu.objects.get (pk=4).course.add(1,2)Copy the code

  • Delete the data

    Stu = stu.objects.filter (s_name=' objects.filter ').first(); stu = stu.objects.filter (s_name=' objects.filter ').first()Copy the code
  • Reset the data

    # if nothing is added, Stu = stu.objects.filter (s_name=' stu.object.filter ').first() # add(2, stu.course. 3) # set stu = stu.objects.filter (s_name=' stu.course.set ').first() stu.course.set([1,3])Copy the code
  • empty

    Stu = stu.objects.filter (s_name=' stu.course.clear ').first() stu.course.clear()Copy the code
  • One-to-one query

    Models import Stu from multi_table. Models import StudentInfoCopy the code
    Student = stu.objects.first () stu_detail=student.si_id stu_detail.s_card student= stu.objects.first () stu_detail=student.si_id stu_detailCopy the code

    # reverse query: Query id number for 410422200205061358 of the student's name stu_info = StudentInfo. Objects. The filter (s_card = '410422200205061358'). The first () Stu = stu_info.stu_STU_info # Reverse query stu.s_name with related_nameCopy the code

  • Many-to-one query

    Models import Course from multi_table. Models import TeacherCopy the code
    Class = course.objects.filter (c_name=' objects.filter ').first() teacher=course.t_id teacher.t_nameCopy the code

    Select * from related_name; Course = teach.objects.first ().teacher_course # turn the object into a query set courses=course.all() # edit the result for c in through the for loop courses: print(c.c_name)Copy the code

  • Many to many

    Stu = stu.objects.filter (s_name=' stu.objects.filter ').first() courses = stu.course.all() for c  in courses: print(c.c_name)Copy the code
    First () students = course = course.objects.filter (c_name=' mathematics ').first() students = course = course.objects.filter (c_name=' mathematics ').first() students = course.course_student.all() for s in students: print(s.s_name)Copy the code

QuerySet common API

When we do a query, we do it with the model name.objects. Model name, actually. The objects is a django. The models. The manager. The object manager, the manager of this class is a “shell” class, he is itself no attributes and methods. His methods are all copied from the QuerySet class by dynamically adding them to Python.

So if we want to learn ORM model lookup operations, we must first learn to use some API on QuerySet.

Returns the method of the new QuerySet
  • filter

  • exclude

  • annotate

  • order_by

  • values

  • values_list

    Similar to VALUES. Except that instead of dictionaries, the QuerySet returned will store tuples.

  • all

  • select_related

    When the data of a model is extracted, the associated data is also extracted in advance. Reduces the number of database queries. Selected_related can only be used in one-to-many or one-to-one, not many-to-many or many-to-one.

    Article = article.objects.get (pk=1) >> article Article. Objects. Select_related ("author").get(pk=2) >> ArticleCopy the code
  • prefetch_related

    This method is very similar to select_related in that it reduces the number of queries when accessing data from multiple tables. This approach is designed to solve the query problem of many-to-one and many-to-many relationships.

  • defer

    In some tables, there might be a lot of fields, but some fields might be a lot of data and you don’t need them, so we can use defer to filter out some fields. This field is similar to VALUES, except that instead of a dictionary, defer returns the model.

  • only

    It is similar to defer, except that defer filters out the specified fields, whereas only extracts only the specified fields.

  • get

  • create

  • get_or_create

    Search for something, return it if it found it, create one if it didn’t.

  • bulk_create

  • count

  • first & last

  • aggregate

  • exists

  • distinct

  • update

  • delete

  • Slicing operation

When does Django convert QuerySet to SQL to execute
  • The iteration
  • Slice using step size
  • Call len
  • Calling the list function
  • judge

9. Configure multiple databases

(Temporarily unavailable, know that you can configure multiple databases, to use the time to learn it)

10. Execute the SQL statement

Manager.raw(raw_query, params=None, translations=None)

SQL with parameters