Python全栈之路-Django(七)

1 创建应用

python manage.py startapp app01

目录结构

app01
|______init__.py
|____admin.py   # Django自带后台管理相关配置
|____apps.py    
|____migrations 
| |______init__.py
|____models.py  # 写类,根据类创建数据库表
|____tests.py   # 单元测试
|____views.py   # 业务处理

可以创建多个应用

python manage.py startapp app02

2 路由系统

2.1 路由系统分类

  • 一一对应:url -> 函数
  • 位置参数:/add-user/(w+)/(d+).html -> def add_user(request,para1,para2)
  • 关键字参数:/edit-user/(?Pw+)/(?Pd+).html -> def edit_user(request,para2,para1)

注意:位置参数方式和关键字参数不建议混合使用

PS:

1 url正则匹配时建议最后加终止符$

url(r'^admin/$', admin.site.urls)

2.位置参数和关键字参数可完成伪静态功能,SEO权重会相对高

2.2 路由系统示例

urls.py

from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^add-user/(w+)/(d+).html', views.add_user),
    url(r'^edit-user/(?P<para1>w+)/(?P<para2>d+).html', views.edit_user),
]

app01.views.py

from django.shortcuts import HttpResponse,render,redirect


# def add_user(request, para1, para2):
#     print(para1,para2)
#     return HttpResponse('...')
# 
# def edit_user(request,para2,para1):
#     print(para1, para2)
#     return HttpResponse('...')

def add_user(request, *args):
    print(para1,para2)
    return HttpResponse('...')
def edit_user(request,**kwargs):
    print(para1, para2)
    return HttpResponse('...')

浏览器访问:http://localhost:8000/add-user/admin/1314.html
并查看后台输出

2.3 路由分发

from django.conf.urls import url,include
from django.contrib import admin

urlpatterns = [
    url(r'^app01/', include('app01.urls')),
    url(r'^app02/', include('app02.urls')),
]

app01.urls.py
from django.conf.urls import url
from app01 import views

urlpatterns = [
    url(r'^index/', views.index),
]

app01.views.py
def index(request):
    return HttpResponse('app01 index')

app02.urls.py
from django.conf.urls import url
from app01 import views

urlpatterns = [
    url(r'^index/', views.index),
]

app02.views.py
def index(request):
    return HttpResponse('app01 index')    


urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^add-user/(w+)/(d+).html', views.add_user),
    url(r'^edit-user/(?P<para1>w+)/(?P<para2>d+).html', views.edit_user),
    url(r'^app01/', include('app01.urls')),
    url(r'^app02/', include('app02.urls')),
    url(r'^',views.index),  # 指定404页面
]

2.4 路由系统别名来反向生成URL

1 在Python代码中的使用(根据名称反向生成URL)

app01.urls.py

from django.conf.urls import url
from app01 import views

urlpatterns = [
    # url(r'^index/(d+)/', views.index, name='n1'),
    url(r'^index/(?P<a1>d+)/', views.index, name='n1'),
]

app01.views.py
def index(request):
    user_list = [
        'alex', 'eric', 'tony'
    ]
    # v = reverse('n1', args=(123,))
    v = reverse('n1', kwargs={'a1': 456, })
    print(v)
    return render(request, 'index.html', {'user_list': user_list})

2 在HTML模板中的使用

app01.urls.py

from django.conf.urls import url
from app01 import views

urlpatterns = [
    # url(r'^index/(d+)/', views.index, name='n1'),
    url(r'^index/(?P<a1>d+)/', views.index, name='n1'),
    url(r'^login/', views.login, name='m1'),
    url(r'^edit/(w+)/', views.edit, name='n2'),
]

app01.veiws.py

def login(request):
    return render(request, 'login.html')

template.login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="{% url "m1" %}" method="post">
    <input type="text">
</form>
</body>
</html>

template.index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <ul>
        {% for row in user_list %}
        <li>{{ row }} | <a href="/app01/edit/{{ row }}/">编辑</a></li>
        <li>{{ row }} | <a href="{% url "n2" row %}">编辑</a></li>
        {% endfor %}
    </ul>
</body>
</html>

2.5 URL别名应用:

不同用户能访问的URL通过别名(简化而且增加可读性)存放在数据库中,便于不同用户的权限管理

3 ORM操作

HTTP请求:url -> 视图(模板+数据)

ORM

  • 操作数据表:
    • 创建表
    • 修改表
    • 删除表
  • 操作数据行

注:ORM利用pymysql、MySQLdb等第三方工具连接数据库

3.1 Django中ORM操作步骤

  1. Django默认使用SQLlite数据库
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}
修改为MySQL
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'db05',
        'USER': 'root',
        'PASSWORD': '123456',
        'HOST': 'localhost',
        'PORT': '3306',
    }
}

2.创建数据库

3.修改与setting.py同级目录下的__init__.py

Django默认使用MySQLdb模块,在Python3中需要将其修改为pymysql模块

import pymysql
pymysql.install_as_MySQLdb()

4.创建类

app01.models.py

from django.db import models


class UserInfo(models.Model):
    nid = models.BigAutoField(primary_key=True)  # 不写此列默认会生成一列列名为id的自增主键列
    username = models.CharField(max_length=32)
    password = models.CharField(max_length=64)

5.注册app01

settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app01',
]

6.创建数据表

$ python3 manage.py makemigrations
Migrations for 'app01':
  app01/migrations/0001_initial.py
    - Create model UserInfo

$ python3 manage.py migrate
Operations to perform:
  Apply all migrations: admin, app01, auth, contenttypes, 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 app01.0001_initial... 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 sessions.0001_initial... OK

7.修改表

from django.db import models


class UserInfo(models.Model):
    nid = models.BigAutoField(primary_key=True)  # 不写此列默认会生成一列列名为id的自增主键列
    user = models.CharField(max_length=32)
    password = models.CharField(max_length=64)
    # age = models.IntegerField(null=True)
    # age = models.IntegerField(default=1)

$ python3 manage.py makemigrations
Did you rename userinfo.username to userinfo.user (a CharField)? [y/N] y
Migrations for 'app01':
  app01/migrations/0002_auto_20170703_0718.py
    - Rename field username on userinfo to user
$ python3 manage.py migrate
Operations to perform:
  Apply all migrations: admin, app01, auth, contenttypes, sessions
Running migrations:
  Applying app01.0002_auto_20170703_0718... OK

8.新增一列

from django.db import models


class UserInfo(models.Model):
    nid = models.BigAutoField(primary_key=True)  # 不写此列默认会生成一列列名为id的自增主键列
    user = models.CharField(max_length=32)
    password = models.CharField(max_length=64)
    # 注意:默认字段是不能为空,要解决该问题,如下
    # age = models.IntegerField(null=True)   # 设置默认可以为空
    age = models.IntegerField(default=1)     # 设置默认值

$ python3 manage.py makemigrations
Migrations for 'app01':
  app01/migrations/0003_userinfo_age.py
    - Add field age to userinfo
$ python3 manage.py migrate
Operations to perform:
  Apply all migrations: admin, app01, auth, contenttypes, sessions
Running migrations:
  Applying app01.0003_userinfo_age... OK

9.创建外键关系

from django.db import models

class UserGroup(models.Model):
    """
    部门表
    """
    title = models.CharField(max_length=32)


class UserInfo(models.Model):
    """
    员工表
    """
    nid = models.BigAutoField(primary_key=True)  # 不写此列默认会生成一列列名为id的自增主键列
    user = models.CharField(max_length=32)
    password = models.CharField(max_length=64)
    # age = models.IntegerField(null=True)
    age = models.IntegerField(default=1)
    # 生成ug_id列
    ug = models.ForeignKey("UserGroup",null=True)

$ python3 manage.py makemigrations
$ python3 manage.py migrate

PS:app01.migrations文件是存放数据库的所有变更记录,不能随意修改和删除

3.2 ORM数据表操作

增删改查

from django.shortcuts import HttpResponse,render,redirect
from app01 import models

def index(request):
    # 增
    # models.UserGroup.objects.create(title='销售部')
    # models.UserInfo.objects.create(
    #     user='wyz',
    #     password='456',
    #     age=18,
    #     ug_id=1
    # )

    # 查
    group_list = models.UserGroup.objects.all()
    print(group_list)   # QuerySet类型 里面包含多个UserGroup对象
    # group_list = models.UserGroup.objects.filter(id=1)
    # group_list = models.UserGroup.objects.filter(id__gt=1)  # 大于
    # group_list = models.UserGroup.objects.filter(id__gte=1) # 大于等于
    # group_list = models.UserGroup.objects.filter(id__lt=2)  # 小于
    # group_list = models.UserGroup.objects.filter(id__lte=2) # 小于等于

    # 删
    # models.UserGroup.objects.filter(id=2).delete()

    # 改
    models.UserGroup.objects.filter(id=2).update(title='公关部')

    return HttpResponse('...')

HTML渲染ORM查找的数据

def index(request):
    # 查
    group_list = models.UserGroup.objects.all()
    print(group_list)   # QuerySet类型 里面包含多个UserGroup对象
    for row in group_list:    # 遍历
        print(row.id, row.title)
    return render(request, 'newindex.html', {"group_list": group_list})

templates.newindex.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <ul>
        {% for row in group_list %}
            <li>{{ row.id }}-{{ row.title }}</li>
        {% endfor %}
    </ul>
</body>
</html>
原文地址:https://www.cnblogs.com/wanyuetian/p/7111628.html