Django

1. 再写N个页面

- url -> 函数
- 函数
urlpatterns = [
    # path('admin/', admin.site.urls),
    # www.xxx.com/index/    -> 函数
    path('index/', views.index),
    path('user/list/', views.user_list),
    path('user/add/', views.user_add),
]
from django.shortcuts import render,HttpResponse

# Create your views here.


def index(request):
    return HttpResponse("hello world")

def user_list(request):
    return HttpResponse("用户列表")

def user_add(request):
    return HttpResponse("添加用户")

2. templates模板

def user_list(request):
    # 1. 默认去APP目录下的templates目录寻找user_list.html
    # (根据APP的注册顺序,逐一去他们的templates目录中寻找)

    # 2. 如果在settings.py中配置了'DIRS': [os.path.join(BASE_DIR,'templates')],(需要提前在settings.py中配置,不配置就是无效)
    # (则会去项目根目录中的templates目录中寻找user_list.html)
    # (如果寻找不到,则会根据APP的注册顺序,就会在每个APP下的templates目录中寻找)
    return render(request, "user_list.html")

3. 静态文件

  • 在开发过程中一般将:

    • 图片
    • CSS
    • JS
    • 第三方插件等
  • 都会当做静态文件处理

3.1 static目录

  1. 在APP目录下创建static文件夹
  2. 引用静态文件
{% load static %}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1-dist/css/bootstrap.css' %}">
    
</head>
<body>
    <h1>用户列表</h1>
    <input type="text" class="btn btn-primary" value="新建">
    <img src="{% static 'img/fm_33.jpg' %}" style="height: 100%; width: 100%;">

    <script src="{% static 'js/jquery-3.7.1.min.js' %}"></script>
    <script src="{% static 'js/plugins/bootstrap-3.4.1-dist/js/bootstrap.js' %}"></script>
</body>
</html>

4. 模板语法

  • 本质上:在HTML中写一些占位符,由数据对这些占位符进行替换和处理
> 视图函数render内部
1. 读取含有模板语法的HTML文件
2. 内部进行渲染(模板语法并执行替换数据)
- 最终得到,只包含HTML标签的字符串
3. 将渲染(替换)完成的HTML返还给用户浏览器
def tpl(request):
    name = '111'
    roles = ['管理员', '队长', '小组长', '保安']
    user_info = {'name':'果汁', 'salary': 10000, 'role': 'CTO'}
    data_list = [
        {'name':'果汁', 'salary': 10000, 'role': 'CTO'},
        {'name':'芦荟', 'salary': 22222, 'role': 'CEO'},
        {'name':'水果', 'salary': 33333, 'role': 'CFO'},
    ]

    return render(
        request,
        "tpl.html",
        {
            'n1': name,
            'n2': roles,
            'n3': user_info,
            'n4': data_list,
        }
        )
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>title</title>
</head>
<body>
    <h1>模板语法的学习</h1>
    <div>{{ n1 }}</div>
    <div>{{ n2 }}</div>

    <div>{{ n2.0 }}</div>
    <div>{{ n2.1 }}</div>
    <div>{{ n2.2 }}</div>
    <div>{{ n2.3 }}</div>

    <div>
        {% for item in n2 %}
            {{item}}
        {% endfor %}
    </div>
    <hr/>
    <hr/>

    {{ n3 }}
    {{ n3.name }}
    {{ n3.salary }}
    {{ n3.role }}

    <ul>
        {% for item in n3.keys %}
            
  • {{ item }}
  • {% endfor %} </ul> <ul> {% for item in n3.values %}
  • {{ item }}
  • {% endfor %} </ul> <ul> {% for k,v in n3.items %}
  • {{ k }} = {{ v }}
  • {% endfor %} </ul> <hr/> <hr/> {{ n4.0 }} {{ n4.1.name }} {{ n4.0.role }} {% for item in n4 %}
    {{ item.name }} / {{ item.salary }}
    {% endfor %} <hr/> <hr/> {% if n1 == "韩超" %} {% elif n1 == "111" %} {% else %} {% endif %} </body> </html>

    案例:伪联通新闻中心

    urlpatterns = [
        # path('admin/', admin.site.urls),
        # www.xxx.com/index/    -> 函数
        path('index/', views.index),
        path('user/list/', views.user_list),
        path('user/add/', views.user_add),
        path('tpl/', views.tpl),
        path('news/', views.news),
    
    ]
    
    def news(request):
        # 1. 定义一些新闻(列表/字典); 或 数据库 或 爬虫爬取数据
        # 向http://www.chinaunicom.com.cn/api/article/NewsByIndex/2/2023/09/news发送请求
        # 第三方模块:requests
        headers = {'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36"}
        url = 'http://www.chinaunicom.com.cn/api/article/NewsByIndex/2/2023/09/news'
        res = requests.get(headers=headers, url= url)
        data_list = res.json()
        # print(data_list)
    
        return render(request, "news.html", {'news_list': data_list})
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
        <h1>联通新闻中心</h1>
        <ul>
            {% for item in news_list %}
                
  • {{ item.news_title }} 时间:{{ item.post_time }}
  • {% endfor %} <hr/> <li>{{ news_list.1.news_title }}</li> <li>{{ news_list.2.news_title }}</li> <li>{{ news_list.3.news_title }}</li> </ul> </body> </html>

    5. 请求和响应

        # 请求和响应
        path('something/', views.something),
    
    def something(request):
        # request是一个对象,内部封装了用户发送过来的所有数据
    
        # 1.获取请求方式
        print(request.method)
    
        # 2.在URL上传递一些参数值 something/?n1=123&n2=999
        print(request.GET)
    
        # 3.在请求体中提交数据
        print(request.POST)
    
        # 【响应】4.将字符串内容返回给请求者 HttpResponse("返回内容")
        # return HttpResponse("返回内容")
    
        # 【响应】5.读取HTML内容 + 渲染(替换) -> 返还给用户,浏览器
        # return render(request, "something.html", {"title": "你干嘛?"})
    
        # 【响应】6.让浏览器重定向到其他页面(将内容返还给浏览器,让浏览器自己去重新请求对应的地址)
        return redirect("https://www.baidu.com")
    

    案例:用户登录

    def login(request):
        if request.method =="GET":
            return render(request, "login.html")
        elif request.method == "POST":
            # 如果是POST请求,获取用户提交的数据,并进行验证
            # print(request.POST)
            username = request.POST.get("user")
            password = request.POST.get("pwd")
    
            if username == "root" and password == "123":
                return redirect("http://www.chinaunicom.com.cn/index.html")
            else:
                return render(request, 'login.html', {"error_msg":"登录失败,请检查用户名或密码是否输入错误"})
    
    # 上述代码简化
    def login(request):
        if request.method =="GET":
            return render(request, "login.html")
    
        # 如果是POST请求,获取用户提交的数据,并进行验证
        # print(request.POST)
        username = request.POST.get("user")
        password = request.POST.get("pwd")
    
        if username == "root" and password == "123":
            return redirect("http://www.chinaunicom.com.cn/index.html")
    
        return render(request, 'login.html', {"error_msg":"登录失败,请检查用户名或密码是否输入错误"})
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
        <h1>用户登录</h1>
        <form action="/login/" method="post">
            {% csrf_token %}
            <input type="text" name="user" placeholder="请输入用户名">
            <input type="password" name="pwd" placeholder="请输入密码">
            <input type="submit" value="提交"> 
            <span style="color: red;">{{ error_msg }}</span>
        </form>
    </body>
    </html>
    

    6. Python直接操作数据库

    • MySQL数据库 + pymysql
    import pymysql
    
    # 1. 链接MySQL
    conn = pymysql.connect(host='127.0.0.1',port=3306,user='root',password='root123',db='unicom',charset='utf8')
    # 创建游标对象
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
    
    # 2. 发送指令
    cursor.execute("insert into admin(username,password,mobile) values('徐泽林','123456','13100204183')")
    conn.commit()
    
    # 3. 关闭连接
    cursor.close()
    conn.close()
    
    • Django开发操作数据库更简单,内部提供了ORM框架

    ORM —> pymysql、MySQLdb、mysqlclient

    6.1 安装第三方模块

    pip install mysqlclient
    

    6.2 ORM

    • ORM可以帮助我们做两件事:
      • 创建、修改、删除数据库中的表(不用写SQL语句)【无法创建数据库】
      • 操作表中的数据(不用写SQL语句)
    6.2.1 创建数据库
    • 启动MySQL服务
    • 自带工具创建数据库
    show databases;
    
    create database 数据库名称 DEFAULT CHARSET utf8 COLLATE utf8_general_ci;
    
    6.2.2 Django连接数据库
    • 在settings.py文件中进行配置和修改
    DATABASES = {
        "default": {
            "ENGINE": "django.db.backends.mysql",   # 数据库类型
            "NAME": "djangotest02",                 # 数据库名称
            "USER": "root",                         # 用户名
            "PASSWORD": "root123",                  # 密码
            "HOST": "127.0.0.1",                    # 主机
            "PORT": "3306",                         # 端口
        }
    }
    
    6.2.3 Django操作表
    • 创建表:在models.py文件中
    class UserInfo(models.Model):
        name = models.CharField(max_length=32)
        password = models.CharField(max_length=64)
        age = models.IntegerField()
    
        
    """
    create table app01_userinfo{
        id bigint auto_increment primary key,
        name varchar(32),
        password varchar(64),
        age int
    }
    """
    
    # 提交数据库变更(需要APP提前注册)
    python manage.py makemigrations
    python manage.py migrate
    
    • 在表中新增列时,由于已存在的列中可能已有数据,所以新增列必须要指定新增列对应的数据

      • 手动输入一个值

        Please select a fix:
         1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
         2) Quit, and let me add a default in models.py
        Select an option: 1
        Please enter the default value now, as valid Python
        The datetime and django.utils.timezone modules are available, so you can do e.g. timezone.now 
        Type 'exit' to exit this prompt
        >>> 1
        
      • 设置默认值

        age = models.IntegerField(default=2)
        
      • 允许为空

        data = models.IntegerField(null=True, blank=True)
        
    • 以后在开发中如果想要对表结构进行调整

      • 在models.py文件中操作类即可
      • 通过命令提交变更表结构
      python manage.py makemigrations
      python manage.py migrate
      
    6.2.4 操作表中的数据
    # from app01 import models
    from app01.models import Department, UserInfo
    
    def orm(request):
        # 测试ORM操作表中的数据
        # models.Department
    
        ########## 1.新建数据 ##########
        # Department.objects.create(title="销售郁")
        # Department.objects.create(title="产品部")
        # Department.objects.create(title="IT部")
        # Department.objects.create(title="运营部")
        # UserInfo.objects.create(name="林泽徐", password="123", age=19)
        # UserInfo.objects.create(name="诺手", password="666")
        # UserInfo.objects.create(name="德玛西亚", password="789456123")
    
        ########## 2.删除数据 ##########
        # UserInfo.objects.filter(id=1).delete()
        # Department.objects.all().delete()
    
        ########## 3.查找数据 ##########
        # 3.1 获取符合条件的所有数据
        # [行对象,行对象,行对象]  QuerySet类型
        # data_list = UserInfo.objects.all()
        # for obj in data_list:
        #     print(obj.id, obj.name, obj.password, obj.age)
        # data_list = [对象,]
        # data_list = UserInfo.objects.filter(id=2)
        # print(data_list)
        # 3.2 获取第一条数据,返回一个对象
        # row_obj = UserInfo.objects.filter(id=2).first()
        # print(row_obj.id, row_obj.name, row_obj.password, row_obj.age)
    
        ########## 4.修改数据 ##########
        # UserInfo.objects.all().update(password="XXXXXX")
        # UserInfo.objects.filter(id=2).update(age="999")
        # UserInfo.objects.filter(name="123").update(age="999")
    
        return HttpResponse("orm成功")
    

    6.3 案例:用户管理

    1. 展示用户列表
    • URL
    • 函数
      • 获取所有用户信息
      • HTML渲染
    def info_list(request):
        # 1. 获取数据库中所有的用户信息
        # [对象, 对象, 对象, ...]
        data_list = UserInfo.objects.all()
    
        return render(request, "info_list.html", {"data_list": data_list})
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
        <h1>INFO列表</h1>
        <a href="/info/add/">添加</a>
        <table border="1px">
            <thead>
                <tr>
                    <th>ID</th>
                    <th>姓名</th>
                    <th>密码</th>
                    <th>年龄</th>
                </tr>
            </thead>
            <tbody>
                {% for obj in data_list %}
                    
                        {{ obj.id }}
                        {{ obj.name}}
                        {{ obj.password}}
                        {{ obj.age }}
                    
                {% endfor %}
            </tbody>
        </table>
    </body>
    </html>
    
    1. 添加用户
    • URL
    • 函数
      • GET,看到页面,输入内容
      • POST,提交 -> 写入到数据库
    def info_add(request):
        if request.method == "GET":
            return render(request, 'info_add.html')
    
        # 获取用户提交的数据
        username = request.POST.get("user")
        password = request.POST.get("password")
        age = request.POST.get("age")
    
        # 添加到数据库
        UserInfo.objects.create(name=username, password=password, age=age)
    
        # 自动跳转至列表页面
        # return redirect("http://127.0.0.1:8000/info/list/")
        return redirect("/info/list/")
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
        <h1>添加用户</h1>
        <form method="post">
            {% csrf_token %}
            <input type="text" name="user" placeholder="请输入用户名">
            <input type="password" name="password" placeholder="请输入密码">
            <input type="text" name="age" placeholder="请输入年龄">
            <input type="submit" value="添加用户">
        </form>
    </body>
    </html>
    
    1. 删除用户
    • URL
    • 函数
    http://127.0.0.1:8000/info/delete/?nid=1
    http://127.0.0.1:8000/info/delete/?nid=2
    
    def 函数(request):
        nid = request.GET.get("nid")
        UserInfo.objects.filter(id=nid).delete()
        return HttpResponse("删除成功")
    

    评论