yum upgrade -y
yum -y install epel-release
yum -y install python3
没有最新的sqlite,后续建立项目app会报错,安装过程看其他文章
pip3 install django
问题:
安装包出现
Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ProxyError
# pip3 install django
WARNING: Running pip install with root privileges is generally not a good idea. Try `pip3 install --user` instead.
Collecting django
Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError(': Failed to establish a new connection: [Errno 101] Network is unreachable',)': /simple/django/
国内几个pip源如下:
阿里云 http://mirrors.aliyun.com/pypi/simple/
中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/
豆瓣(douban) http://pypi.douban.com/simple/
清华大学 https://pypi.tuna.tsinghua.edu.cn/simple/
中国科学技术大学 http://pypi.mirrors.ustc.edu.cn/simple/
可以用清华大学的源
# pip3 install --upgrade pip -i https://pypi.tuna.tsinghua.edu.cn/simple/
WARNING: Running pip install with root privileges is generally not a good idea. Try `pip3 install --user` instead.
Collecting pip
Downloading https://pypi.tuna.tsinghua.edu.cn/packages/43/84/23ed6a1796480a6f1a2d38f2802901d078266bda38388954d01d3f2e821d/pip-20.1.1-py2.py3-none-any.whl (1.5MB)
100% |████████████████████████████████| 1.5MB 436kB/s
Installing collected packages: pip
# pip3 install django -i https://pypi.tuna.tsinghua.edu.cn/simple/
安装完成之后我们可以通过 python3 -m django --version 查看当前Django版本
[root@localhost ~]# python3 -m django --version
3.0.7
django-admin.py startproject testapi
tree djangoDemo
testapi/
├── tesyapi
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── manage.py
1、testapi/testapi: 项目最初的Python包
2、testapi/init.py: 一个空文件,声明所在目录的包为一个Python包
3、testapi/settings.py: 管理项目的配置信息
4、testapi/urls.py: 声明请求url的映射关系
5、testapi/wsgi.py: python程序和web服务器的通信协议
6、manage.py: 一个命令行工具,用来和Django项目进行交互,如前面创建项目就用到了该文件。
setting.py 文件用来配置整个项目,里面的字段非常多,所以在开始之前有必要先都了解一下默认的配置有哪些
"""
Django settings for DjangoModel project.
Generated by 'django-admin startproject' using Django 3.0.8.
For more information on this file, see
https://docs.djangoproject.com/en/3.0/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.0/ref/settings/
"""
import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
# 项目的相对路径,启动服务的时候会运行这个文件所在路径的manage.py
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
# 安全密钥
SECRET_KEY = 'p@k)sb7u^1t#1t@e!jaj)cn9fd3e9gb1vjp^4y)irl(=jmx$_f'
# SECURITY WARNING: don't run with debug turned on in production!
# 是否开启Debug
DEBUG = True
# 允许访问的主机ip,可以用通配符*
ALLOWED_HOSTS = ["*"]
# Application definition
# 用来注册App 前6个是django自带的应用
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'api.apps.AppConfig', #新建的应用需要在这里注册
]
# 中间件 ,需要加载的中间件。比如在请求前和响应后根据规则去执行某些代码的方法
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',
]
# 指定URL列表文件 父级URL配置
ROOT_URLCONF = 'DjangoModel.urls'
# 加载网页模板路径
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')]
,
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
# WSGI的配置文件路径
WSGI_APPLICATION = 'DjangoModel.wsgi.application'
# Database
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases
# 数据库配置 默认的数据库为sqlite
DATABASES = {
'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
'ENGINE': 'django.db.backends.mysql',
'NAME': 'djangoModel',
'USER': 'root',
'PASSWORD': '123456',
'HOST': 'localhost',
'PORT': 3306,
}
}
# Password validation
# https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/3.0/topics/i18n/
# 语言设置 默认英语, 中文是zh-hans
LANGUAGE_CODE = 'zh-hans'
# 时区设置,中国的是:Asia/Shanghai
TIME_ZONE = 'Asia/Shangha'
# i18n字符集是否支持
USE_I18N = True
USE_L10N = True
# 是否使用timezone
# 保证存储到数据库中的是 UTC 时间;
# 在函数之间传递时间参数时,确保时间已经转换成 UTC 时间;
USE_TZ = True
# 静态文件路径
STATIC_URL = '/static/'
现在,打开 应用项目/settings.py 。这是个包含了 Django 项目设置的 Python 模块。
通常,这个配置文件使用 SQLite 作为默认数据库。如果你不熟悉数据库,或者只是想尝试下 Django,这是最简单的选择。Python 内置 SQLite,所以你无需安装额外东西来使用它。当你开始一个真正的项目时,你可能更倾向使用一个更具扩展性的数据库,例如 PostgreSQL,避免中途切换数据库这个令人头疼的问题。
如果你使用了 SQLite 以外的数据库,请确认在使用前已经创建了数据库。你可以通过在你的数据库交互式命令行中使用 “CREATE DATABASE database_name;” 命令来完成这件事。
如果你使用 SQLite,那么你不需要在使用前做任何事——数据库会在需要的时候自动创建。
编辑 mysite/settings.py 文件前,先设置 TIME_ZONE 为你自己时区。
在Django的配置文件settings.py中,有两个配置参数是跟时间与时区有关的,分别是TIME_ZONE和USE_TZ
如果USE_TZ设置为True时,Django会使用系统默认设置的时区,即America/Chicago,此时的TIME_ZONE不管有没有设置都不起作用。
如果USE_TZ 设置为False,而TIME_ZONE设置为None,则Django还是会使用默认的America/Chicago时间。若TIME_ZONE设置为其它时区的话,则还要分情况,如果是Windows系统,则TIME_ZONE设置是没用的,Django会使用本机的时间。如果为其他系统,则使用该时区的时间,入设置USE_TZ = False, TIME_ZONE = ‘Asia/Shanghai’, 则使用上海的UTC时间。
[root@localhost djangoDemo]# python3 manage.py runserver 8000
本机可以正常访问,从外部无法访问这个服务器,端口就打不开
抓包发现
服务器返回了rst,ack,给了个重置复位,说明对外端口并没有打开。
仔细观察
对外服务地址不是0.0.0.0而是127.0.0.1,说明只有127.0.0.1能访问
重新执行命令
ALLOWED_HOSTS = [’*’] #在这里请求的host添加了*
接下来要引入一个APP的概念,举个例子我们需要开发一个restful api接口应用,我们可以把每条业务线都看做一个App。一个项目可包含多个app,一个app可在多个项目。
在终端项目目录下执行
[root@localhost djangoDemo]# python3 manage.py startapp api
这个是在win下pycharm创建的结构
D:.
│ db.sqlite3
│ manage.py
│
├─.idea
│ │ .gitignore
│ │ dataSources.local.xml
│ │ dataSources.xml
│ │ deployment.xml
│ │ misc.xml
│ │ modules.xml
│ │ testapi.iml
│ │ workspace.xml
│ │
│ ├─dataSources
│ │ 1244ffe6-5bf8-4454-be92-1438a9a3d050.xml
│ │
│ └─inspectionProfiles
│ profiles_settings.xml
│
├─api
│ │ admin.py
│ │ apps.py
│ │ models.py
│ │ tests.py
│ │ urls.py
│ │ views.py
│ │ __init__.py
│ │
│ ├─migrations
│ │ │ 0001_initial.py
│ │ │ 0002_auto_20180306_0928.py
│ │ │ __init__.py
│ │ │
│ │ └─__pycache__
│ │ 0001_initial.cpython-36.pyc
│ │ 0001_initial.cpython-38.pyc
│ │ 0002_auto_20180306_0928.cpython-36.pyc
│ │ 0002_auto_20180306_0928.cpython-38.pyc
│ │ __init__.cpython-36.pyc
│ │ __init__.cpython-38.pyc
│ │
│ ├─utils
│ │ │ auth.py
│ │ │ permission.py
│ │ │ throttle.py
│ │ │
│ │ └─__pycache__
│ │ auth.cpython-36.pyc
│ │ permission.cpython-36.pyc
│ │ permission.cpython-38.pyc
│ │ throttle.cpython-36.pyc
│ │ throttle.cpython-38.pyc
│ │
│ └─__pycache__
│ admin.cpython-36.pyc
│ admin.cpython-38.pyc
│ apps.cpython-36.pyc
│ apps.cpython-38.pyc
│ models.cpython-36.pyc
│ models.cpython-38.pyc
│ urls.cpython-38.pyc
│ views.cpython-36.pyc
│ views.cpython-38.pyc
│ __init__.cpython-36.pyc
│ __init__.cpython-38.pyc
│
├─templates
└─testapi
│ asgi.py
│ settings.py
│ urls.py
│ wsgi.py
│ __init__.py
│
└─__pycache__
settings.cpython-38.pyc
urls.cpython-38.pyc
wsgi.cpython-38.pyc
__init__.cpython-38.pyc
项目根的urls.py->应用api下的urls.py->应用api下的views.py
testapi/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('api/', include('api.urls')),
path('admin/', admin.site.urls),
]
api/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('order/', views.OrderView.as_view(), name='order'),
]
api/views.py
from django.shortcuts import render,HttpResponse
from django.http import JsonResponse
from rest_framework.views import APIView
from rest_framework.request import Request
from rest_framework import exceptions
from rest_framework.authentication import BasicAuthentication
from api.utils.permission import SVIPPermission
from api.utils.permission import MyPermission1
from api.utils.throttle import VisitThrottle
from api import models
ORDER_DICT = {
1:{
'name': "媳妇",
'age':18,
'gender':'男',
'content':'...'
},
2:{
'name': "老狗",
'age':19,
'gender':'男',
'content':'...。。'
},
}
def md5(user):
import hashlib
import time
ctime = str(time.time())
m = hashlib.md5(bytes(user,encoding='utf-8'))
m.update(bytes(ctime,encoding='utf-8'))
return m.hexdigest()
class AuthView(APIView):
"""
用于用户登录认证
"""
authentication_classes = []
permission_classes = []
throttle_classes = [VisitThrottle,]
def post(self,request,*args,**kwargs):
ret = {'code':1000,'msg':None}
try:
user = request._request.POST.get('username')
pwd = request._request.POST.get('password')
obj = models.UserInfo.objects.filter(username=user,password=pwd).first()
if not obj:
ret['code'] = 1001
ret['msg'] = "用户名或密码错误"
# 为登录用户创建token
token = md5(user)
# 存在就更新,不存在就创建
models.UserToken.objects.update_or_create(user=obj,defaults={'token':token})
ret['token'] = token
except Exception as e:
ret['code'] = 1002
ret['msg'] = '请求异常'
return JsonResponse(ret)
class OrderView(APIView):
"""
订单相关业务(只有SVIP用户有权限)
"""
def get(self,request,*args,**kwargs):
# request.user
# request.auth
self.dispatch
ret = {'code':1000,'msg':None,'data':None}
try:
ret['data'] = ORDER_DICT
except Exception as e:
pass
return JsonResponse(ret)
class UserInfoView(APIView):
"""
订单相关业务(普通用户、VIP)
"""
permission_classes = [MyPermission1, ]
def get(self,request,*args,**kwargs):
return HttpResponse('用户信息')
在 Django 里写一个数据库驱动的 Web 应用的第一步是定义模型 - 也就是数据库结构设计和附加的其它元数据
设计哲学
模型是真实数据的简单明确的描述。它包含了储存的数据所必要的字段和行为。Django 遵循 DRY Principle 。它的目标是你只需要定义数据模型,然后其它的杂七杂八代码你都不用关心,它们会自动从模型生成。
来介绍一下迁移 - 举个例子,不像 Ruby On Rails,Django 的迁移代码是由你的模型文件自动生成的,它本质上是个历史记录,Django 可以用它来进行数据库的滚动更新,通过这种方式使其能够和当前的模型匹配
在这个投票应用中,需要创建两个模型:问题 Question 和选项 Choice。Question 模型包括问题描述和发布时间。Choice 模型有两个字段,选项描述和当前得票数。每个选项属于一个问题。
这些概念可以通过一个 Python 类来描述。按照下面的例子来编辑 polls/models.py 文件
# vi polls/models.py
from django.db import models
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
# vi mysite/settings.py
在这里把新建的应用添加进去
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'api.apps.ApiConfig', #这里
]
生成迁移数据
[root@localhost migrations]# python3 manage.py makemigrations api
迁移到数据库
python manage.py migrate
通过运行 makemigrations 命令,Django 会检测你对模型文件的修改(在这种情况下,你已经取得了新的),并且把修改的部分储存为一次 迁移。
迁移是 Django 对于模型定义(也就是你的数据库结构)的变化的储存形式 - 它们其实也只是一些你磁盘上的文件。如果你想的话,你可以阅读一下你模型的迁移数据,它被储存在 polls/migrations/0001_initial.py 里。别担心,你不需要每次都阅读迁移文件,但是它们被设计成人类可读的形式,这是为了便于你手动调整Django的修改方式。
Django 有一个自动执行数据库迁移并同步管理你的数据库结构的命令 - 这个命令是 migrate,我们马上就会接触它 - 但是首先,让我们看看迁移命令会执行哪些 SQL 语句。sqlmigrate 命令接收一个迁移的名称,然后返回对应的 SQL:
[root@localhost djangoDemo]# python3 manage.py sqlmigrate polls 0001
BEGIN;
--
-- Create model Question
--
CREATE TABLE "polls_question" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "question_text" varchar(200) NOT NULL, "pub_date" datetime NOT NULL);
--
-- Create model Choice
--
CREATE TABLE "polls_choice" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "choice_text" varchar(200) NOT NULL, "votes" integer NOT NULL, "question_id" integer NOT NULL REFERENCES "polls_question" ("id") DEFERRABLE INITIALLY DEFERRED);
CREATE INDEX "polls_choice_question_id_c5b4b260" ON "polls_choice" ("question_id");
COMMIT;
输出的内容和你使用的数据库有关
数据库的表名是由应用名(polls)和模型名的小写形式( question 和 choice)连接而来。(如果需要,你可以自定义此行为。)
主键(IDs)会被自动创建。(当然,你也可以自定义。)
默认的,Django 会在外键字段名后追加字符串 “_id” 。(同样,这也可以自定义。)
外键关系由 FOREIGN KEY 生成。你不用关心 DEFERRABLE 部分,它只是告诉 PostgreSQL,请在事务全都执行完之后再创建外键关系。
生成的 SQL 语句是为你所用的数据库定制的,所以那些和数据库有关的字段类型,比如 auto_increment (MySQL)、 serial (PostgreSQL)和 integer primary key autoincrement (SQLite),Django 会帮你自动处理。那些和引号相关的事情 - 例如,是使用单引号还是双引号 - 也一样会被自动处理。
这个 sqlmigrate 命令并没有真正在你的数据库中的执行迁移 - 相反,它只是把命令输出到屏幕上,让你看看 Django 认为需要执行哪些 SQL 语句。这在你想看看 Django 到底准备做什么,或者当你是数据库管理员,需要写脚本来批量处理数据库时会很有用。
现在,再次运行 migrate 命令,在数据库里创建新定义的模型的数据表:
[root@localhost djangoDemo]# python3 manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, polls, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying polls.0001_initial... OK
Applying sessions.0001_initial... OK
迁移是非常强大的功能,它能让你在开发过程中持续的改变数据库结构而不需要重新删除和创建表 - 它专注于使数据库平滑升级而不会丢失数据。我们会在后面的教程中更加深入的学习这部分内容,现在,你只需要记住,改变模型需要这三步:
编辑 models.py 文件,改变模型。
运行 python manage.py makemigrations 为模型的改变生成迁移文件。
运行 python manage.py migrate 来应用数据库迁移。
略
mysql -uroot -p
mysql> create database djangoModel;
Query OK, 1 row affected (0.01 sec)
import pymysql as pymysql
pymysql.version_info = (1, 3, 13, "final", 0)
pymysql.install_as_MySQLdb()
新的mysql对加密的要求,未安装报错
RuntimeError: cryptography is required for sha256_password or caching_sha2_password
pip install cryptography
[root@localhost djangoDemo]# python3 manage.py createsuperuser
Username (leave blank to use 'root'): admin
Email address: [email protected]
Password:
Password (again):
启动开发服务器
Django 的管理界面默认就是启用的。让我们启动开发服务器,看看它到底是什么样的。
如果开发服务器未启动,用以下命令启动它:
[root@localhost djangoDemo]# python3 manage.py runserver 0:8000
Watching for file changes with StatReloader
Performing system checks...
System check identified no issues (0 silenced).
June 15, 2020 - 08:48:09
Django version 3.0.7, using settings 'djangoDemo.settings'
Starting development server at http://0:8000/
Quit the server with CONTROL-C.
但是我们的投票应用在哪呢?它没在索引页面里显示。
只需要再做一件事:我们得告诉管理员,问题 Question 对象需要一个后台接口。打开 polls/admin.py 文件,把它编辑成下面这样:
# vi polls/admin.py
加入以下内容
from django.contrib import admin
from .models import Question
admin.site.register(Question)