Django入门到放弃 学习笔记 04

跟b站武沛齐老师的视频学习
对学习过程进行一些记录以便复习 同时自我督促 :D冲鸭

视频链接: 15天django入门到放弃-哔哩哔哩.

前言

之前所学 Django 的两个非主流做法:

  1. 自己创建 app —— Django 有特别的语句用于创建 app。
  2. 使用 pymysql —— Django 框架中自带 ORM,不需要自己写 sql 语句。

重新认识框架

创建 app:python manage.py startapp appname

结构:

  • admin Django 自带后台管理相关配置
  • models 写类,根据类创建数据库表
  • tests 单元测试
  • views 业务处理,可以是一个文件夹

路由系统

正则表达式

因为 GET 传参不利于 SEO(搜索引擎优化),修改传参方式:
原:静态路由
  http://127.0.0.1:8000/edit/?nid=1
  path(‘edit/’, views.edit),
  def edit(request):
    request.GET.get(‘nid’)
    return HttpResponse(’…’)
现:动态路由
  http://127.0.0.1:8000/edit/1
  path(‘edit/(\w+)’, views.edit),
  def edit(request, nid):
    return HttpResponse(’…’)

几种表达方式:

url(r'^edit/(\w+)/(\w+)/', views.edit),
url(r'^edit/(?P<a1>\w+)/(?P<a2>\w+)/', views.edit),
url(r'^edit', views.edit), # editlsdfgag
url(r'^edit$', views.edit), # 终止符
url(r'^edit/(\w+).html', views.edit), # 伪静态

路由分发

urls.py

url(r'^app01/', include('app01.urls')),

app01 urls.py

url(r'^index.html$/', views.index),

总路由

	...
	`url(r'^', function),
]

def function(request):
	...

别名反生成URL

后端:

url(r'^index.html$/', views.index, name='n1'),

def xxx(request):
	v = reverse('n1')  # v = '/index/'
url(r'^index/(\w+)/', views.index, name='n2'),

def xxx(request):
	v = reverse('n2', args=(1, )  # v = '/index/1/'
url(r'^index/?P<a>(\w+)/', views.index, name='n3'),

def xxx(request):
	v = reverse('n3', kwargs={'a1': 111}  # v = '/index/111/'

前端:

<form method="POST" action="{% url 'n1' %}">
<form method="POST" action="{% url 'n2' i %}">

ORM 操作

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

ORM
操作表:创建表、修改表、删除表
操作数据行:增、删、改、查

不直接连接数据库,利用 pymysql 第三方工具连接数据库
默认:
SQLlite
默认:mysql -> MYSQLDB(修改 django 默认连接 MySQL 方式)

基础配置及建表

settings.py 中:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}

改为:

DATABASES = {
    'default': {
    'ENGINE': 'django.db.backends.mysql',
    'NAME':'dbname',
    'USER': 'root',
    'PASSWORD': 'xxx',
    'HOST': 'localhost',
    'PORT': 3306,
    }
}

__init__.py 中添加:

import pymysql
pymysql.install_as_MySQLdb() 

settings.py INSTALLED_APPS 中注册app;
app models.py 中写表操作:

from django.db import models

class UserInfo(models.Model):
    nid = models.BigAutoField(primary_key=True) # 可以不写,会自动生成一列 int 型自增主键 id
    username = models.CharField(max_length=32)
    password = models.CharField(max_length=64)

执行命令创建数据表:
python manage.py makemigrations
python manage.py migrate

若在已经有数据的表中增加列的两种方法:

age = models.IntegerField(null=True) # 可以为空
age = models.IntegerField(default=1) # 设置默认值

若设置外键,Django 会自动加上 _id:

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)
    username = models.CharField(max_length=32)
    password = models.CharField(max_length=64)
    age = models.IntegerField(default=1)
    #ug_id
    ug = models.ForeignKey(to="UserGroup", on_delete=models.DO_NOTHING, null=True)

migrations 文件夹中存放了每一次操作的记录:

表操作

def index(request):
    
    from app01 import models
    # 新增
    models.UserGroup.objects.create(title='销售部')
    models.UserInfo.objects.create(username='root', password='pwd', age=18, ug_id=1) # 注意:ug 代表一行数据,赋值时应给 ug_id 赋值
    # 查找
    group_list = models.UserGroup.objects.all() # 得到的数据形如: <QuerySet [<UserGroup: UserGroup object>, <UserGroup: UserGroup object>]>
    group_list = models.UserGroup.objects.filter(id=1, title='销售部') # and关系
    group_list = models.UserGroup.objects.filter(id__gt=1) # 小于 __lt
    for row in group_list:
        print(row.id, row.title) # 1 销售部
    result = models.UserGroup.objects.filter(id=1).first() # 只取一个,得到数据为 object 类型
    # 删除
    models.UserGroup.objects.filter(id=1).delete()
    # 更新
    models.UserGroup.objects.filter(id=1).update('公关部')

关联(对象方式):

# 正向操作 外键字段
obj = models.UserInfo.objects.all().first()
print(obj.name, obj.age, obj.ut.title) # 可以一直关联下去
# 反向操作 表名_set
obj = models.UserType.objects.all().first()
for row in obj.userinfo_set.all():
	print(row.name, row.age)

取部分列(values 方式):

# 正向
models.UserInfo.objects.all() # 得到对象
models.UserInfo.objects.all().values('id', 'name') # 得到字典
models.UserInfo.objects.all().values_list('id', 'name') # 得到元组
# 后两种方式跨表取值:
models.UserInfo.objects.all().values('ut__title') 

# 反向
models.UserType.objects.values('id', 'title', 'userinfo') # 小写的表名 取到id
models.UserType.objects.values('id', 'title', 'userinfo__name')

视图函数

CBV( class base views)
FBV(function base views)

re_path(r"^login.html/$", views.Login.as_view()),
from django.views import View

class Login(View):

    def dispatch(self, request, *args, **kwargs):
        print('before')
        obj = super(Login, self).dispatch(request, *args, **kwargs)
        print('after')
        return obj

    def get(self, request):
        return HttpResponse('login.get')

    def post(self, request):
        return HttpResponse('login.post')

分页

Django 自带

def index(request):

    # for i in range(300):
    #     name = "root" + str(i)
    #     models.UserInfo.objects.create(username=name, age=0)

    from django.core.paginator import Paginator, Page, EmptyPage, PageNotAnInteger

    current_page = request.GET.get('page')

    user_list = models.UserInfo.objects.all()
    paginator = Paginator(user_list, 10)
    # per_page: 每页显示条目数量
    # count:    数据总个数
    # num_pages:总页数
    # page_range:总页数的索引范围,如: (1,10),(1,200)
    # page:     page对象
    try:
        posts = paginator.page(current_page)
    except EmptyPage as e:
         posts = paginator.page(1)
    except PageNotAnInteger as e:
         posts = paginator.page(1)
        # has_next              是否有下一页
        # next_page_number      下一页页码
        # has_previous          是否有上一页
        # previous_page_number  上一页页码
        # object_list           分页之后的数据列表
        # number                当前页
        # paginator             paginator对象

    return render(request, 'index.html', {'posts': posts})

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>用户列表</h1>
    <ul>
        {% for row in posts.object_list %}
        <li>{{ row.username }}</li>
        {% endfor %}
    </ul>
    <div>
        {% if posts.has_previous %}
        <a href="/index.html/?page={{ posts.previous_page_number }}">上一页</a>
        {% endif %}

        {% for num in posts.paginator.page_range %}
        <a href="/index.html/?page={{ num }}">{{ num }}</a>
        {% endfor %}

        {% if posts.has_next %}
        <a href="/index.html/?page={{ posts.next_page_number }}">下一页</a>
        {% endif %}
    </div>
</body>
</html>

自己写分页

class PageInfo(object):

    def __init__(self, current_page, all_count, per_page):
        """
        :param current_page: 当前页码
        :param all_count: 总个数
        :param per_page: 每页个数
        """
        try:
            self.current_page = int(current_page)
        except Exception as e:
            self.current_page = 1
        self.per_page = per_page
        # 计算总页数
        all_pager, b = divmod(all_count, per_page)
        if b:
            self.all_pager = all_pager + 1

    def start(self):
        return ((self.current_page - 1) * self.per_page)

    def end(self):
        return  (self.current_page * self.per_page)

    def pager(self):
        page_list = []
        for i in range(1, self.all_pager):
            if i == self.current_page:
                temp = "<a style='display:inline-block; padding:5px; margin:5px; background-color:red;' href='/custom.html?page=%s'>%s </a>" % (i, i)
            else:
                temp = "<a style='display:inline-block; padding:5px; margin:5px;' href='/custom.html?page=%s'>%s </a>" % (i, i)
            page_list.append(temp)
        return ''.join(page_list) # 将列表中每个元素拼接


def custom(request):

    # 获取总个数
    all_count = models.UserInfo.objects.all().count()

    current_page = request.GET.get('page')
    page_info = PageInfo(current_page, all_count, 10)
    user_list = models.UserInfo.objects.all()[page_info.start():page_info.end()]

    return render(request, 'custom.html', {'user_list': user_list, 'page_info': page_info})

custom.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>用户列表</h1>
    <ul>
        {% for row in user_list %}
        <li>{{ row.username }}</li>
        {% endfor %}
    </ul>
    {{ page_info.pager|safe }}
</body>
</html>

完善并整合成一个 UTIL,utils.pager

class PageInfo(object):

    def __init__(self, current_page, all_count, per_page, show_page, base_url):
        """
        :param current_page: 当前页码
        :param all_count: 总个数
        :param per_page: 每页个数
        """
        try:
            self.current_page = int(current_page)
        except Exception as e:
            self.current_page = 1
        self.per_page = per_page
        self.show_page = show_page
        self.base_url = base_url
        # 计算总页数
        all_pager, b = divmod(all_count, per_page)
        if b:
            self.all_pager = all_pager + 1

    def start(self):
        return ((self.current_page - 1) * self.per_page)

    def end(self):
        return  (self.current_page * self.per_page)

    def pager(self):
        # page_list = []
        # for i in range(1, self.all_pager):
        #     if i == self.current_page:
        #         temp = "<a style='display:inline-block; padding:5px; margin:5px; background-color:red;' href='/custom.html?page=%s'>%s </a>" % (i, i)
        #     else:
        #         temp = "<a style='display:inline-block; padding:5px; margin:5px;' href='/custom.html?page=%s'>%s </a>" % (i, i)
        #     page_list.append(temp)
        # return ''.join(page_list) # 将列表中每个元素拼接
        page_list = []
        half = int((self.show_page - 1)/2)

        if self.show_page > self.all_pager:
            begin = 1
            stop = self.all_pager + 1
        else:
            begin = self.current_page - half
            begin = max(begin, 1)
            stop = begin + self.show_page
            stop = min(stop, self.all_pager + 1)
            begin = stop - self.show_page

        if self.current_page <= 1:
            pre = "<li><a href='#'>上一页 </a></li>"
        else:
            pre = "<li><a href='%s?page=%s'>上一页 </a></li>" % (self.base_url, self.current_page - 1)
        page_list.append(pre)

        for i in range(begin, stop):
            if i == self.current_page:
                temp = "<li class='active'><a href='%s?page=%s'>%s </a></li>" % (self.base_url, i, i)
            else:
                temp = "<li><a href='%s?page=%s'>%s </a></li>" % (self.base_url, i, i)
            page_list.append(temp)

        if self.current_page >= self.all_pager:
            next = "<li><a href='%s?page=#'>下一页 </a>>/li>" % (self.base_url)
        else:
            next = "<li><a href='%s?page=%s'>下一页 </a></li>" % (self.base_url, self.current_page + 1)
        page_list.append(next)

        return ''.join(page_list)  # 将列表中每个元素拼接

调用:

def custom(request):

    # 获取总个数
    all_count = models.UserInfo.objects.all().count()

    current_page = request.GET.get('page')
    page_info = PageInfo(current_page, all_count, 10, 5, '/custom.html')
    user_list = models.UserInfo.objects.all()[page_info.start():page_info.end()]

    return render(request, 'custom.html', {'user_list': user_list, 'page_info': page_info})

前端:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="/static/plugins/bootstrap-3.4.1-dist/css/bootstrap.css">
</head>
<body>
    <h1>用户列表</h1>
    <ul>
        {% for row in user_list %}
        <li>{{ row.username }}</li>
        {% endfor %}
    </ul>
    <nav aria-label="Page navigation">
      <ul class="pagination">
        <li>
          <a href="#" aria-label="Previous">
            <span aria-hidden="true">&laquo;</span>
          </a>
        </li>
        {{ page_info.pager|safe }}
        <li>
          <a href="#" aria-label="Next">
            <span aria-hidden="true">&raquo;</span>
          </a>
        </li>
      </ul>
    </nav>
</body>
</html>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值