Django 3 学习笔记

点击上方“编程派”,选择设为“设为星标”

优质文章,第一时间送达!

作者:国光

出处:https://www.sqlsec.com/

Django是一个文档很全的框架,学习的时候老是遇到一些坑,这里就顺便记录一下,以便后面使用,同时也希望本文可以帮助到其他的朋友。

开发环境

操作系统:macOS Cataline 10.15.3

Python:pyenv 安装的 pypy3.6-7.3.0 (PyPy解释器平均比我们平时使用的CPython快4.4倍)

Django:Django 3.0.3

相关依赖

MySQL

macOS下Django3在连接MySQL会出一些问题,解决如下:

# 确保 pip 是最新版本
$ pip install --upgrade pip

# 临时在当前的shell环境中配置一个 openssl 变量
export LDFLAGS="-L/usr/local/opt/openssl/lib $LDFLAGS"
export CPPFLAGS="-I/usr/local/opt/openssl/include $CPPFLAGS"

$ pip install mysqlclient

pillow

models.py中含有ImageField图片类型的时候,如果pillow没有安装好的话 会报错:

image = models.ImageField(upload_to='avatar/%Y/%m', verbose_name='头像', max_length=100)

解决方法是macOS下安装配置好zlib即可:

# 安装 zlib
$ brew install zlib

# 链接 zlib 会提示
$ brew link zlib --force

Warning: Refusing to link macOS-provided software: zlib
For compilers to find zlib you may need to set:
  export LDFLAGS="-L/usr/local/opt/zlib/lib"
  export CPPFLAGS="-I/usr/local/opt/zlib/include"

根据上述提示,进行如下操作:

# 临时在当前的shell环境中配置一个 zlib 变量
export LDFLAGS="-L/usr/local/opt/zlib/lib"
export CPPFLAGS="-I/usr/local/opt/zlib/include"

$ pip install pillow

目录配置

templates

模板目录 Python 命令行创建的 Django 项目默认是没有自动生成这个目录的,首先项目目录下新建templates文件夹,然后配置一下settings:

settings.py

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')], # 将 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',
            ],
        },
    },
]

static

该目录存放一些css js 之类的静态文件,也得手动到 settings.py 添加配置一下:

settings.py

STATIC_URL = '/static/'
STATICFILES_DIRS = [(os.path.join(BASE_DIR, 'static'))]

apps

当项目下的app太多的时候,项目的目录结构看上去就会比较混乱,一个解决办法就是将项目下的所有app都放到一个apps的文件夹中,首先项目下新建apps文件夹,接着手动到 settings.py 添加配置一下:

settings.py

import os
import sys

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, os.path.join(BASE_DIR, 'apps')) # 将 apps 文件夹添加到 BASE_DIR中

media

media文件夹用来存放用户上传的图片资料等,首先配置下settings.py

settings.py

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',
                'django.template.context_processors.media', # 添加 media 模板
            ],
        },
    },
]

接着配置 media 根目录变量:

settings.py

MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

配置好之后在 urls.py 里面配置下 media 的路由规则:

urls.py

from django.urls import path, re_path
from django.views.static import serve
from project.settings import MEDIA_ROOT

urlpatterns = [
    path('admin/', admin.site.urls),
      # 配置 media 的处理
    re_path('media/(?P<path>.*)', serve, {'document_root': MEDIA_ROOT}, name='org_list'),
]

下面看一下 简单的 引用 meida 中图片文件的实例:

models.py

class CourseOrg(models.Model):
    ...
    image = models.ImageField(upload_to='org/%Y/%m', verbose_name='logo', max_length=100)
    ...

前端调用显示 media 里的文件

<img width="200" height="120" class="scrollLoading" data-url="{{ MEDIA_URL }}{{ course_org.image }}"/>

实用插件

验证码

项目地址:https://github.com/mbi/django-simple-captcha

$ pip install django-simple-captcha

安装好之后,在settings.py引用即可:

settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'captcha',  # 引用验证码插件
]

引用完成后,更新下数据库的信息,因为这个验证码信息是存放在本地数据库中的:

$ python manage.py makemigrations
$ python manage.py migrate

数据库更新成功后可以在数据库下看到 captcha_captchastore 表名,接着得配置下验证码的url路由规则:

urls.py

urlpatterns = [
    path('admin/', admin.site.urls),
    path('captcha/', include('captcha.urls')),
]

Form表单中定义如下:

forms.py

from django import forms
from captcha.fields import CaptchaField

class RegisterForm(forms.Form):
    email = forms.EmailField(required=True)
    password = forms.CharField(required=True, min_length=5)
    captcha = CaptchaField(error_messages={'invalid': '验证码错误'})

Views里面实例化这个表单类:

views.py

class RegisterView(View):
    def get(self, request):
        register_form = RegisterForm()
        return render(request, 'register.html', {
            'register_form': register_form
        })

views.py里面 返回了register_form到前端,接着前端可以直接调用 验证码:

<div class="form-group marb8 captcha1">
<label>验证码</label>
{{ register_form.captcha }}
</div>

分页

项目地址:https://github.com/jamespacileo/django-pure-pagination

$ pip install django-pure-pagination

安装好之后,在settings.py引用即可:

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

views里面的基本用法:

views.py

from pure_pagination import Paginator, EmptyPage, PageNotAnInteger

class OrgView(View):
    """
    课程机构列表功能显示
    """
    def get(self, request):
        # 课程机构
        all_orgs = CourseOrg.objects.all()

        # 官方提倡的写法
        try:
            page = request.GET.get('page', 1)
        except PageNotAnInteger:
            page = 1

        # 将数据库中 查询的 all_orgs 分页 每页显示5个
        p = Paginator(all_orgs, 5, request=request)
        orgs = p.page(page)
        return render(request, 'org-list.html', {
            'all_orgs': orgs,  # 分页的结果传给前端
        })

前端分页的引用:

<div class="pageturn">
<ul class="pagelist">
<!-- 判断是是否有上一页 -->
  {% if all_orgs.has_previous %}
  <li class="long"><a href="?{{ all_orgs.previous_page_number.querystring }}">上一页</a></li>
  {% endif %}

<!-- 显示中间页数 和 高亮 当前页 -->
  {% for page in all_orgs.pages %}
  {% if page %}
  {% ifequal page all_orgs.number %}
  <li class="active"><a href="?{{ page.querystring }}" class="page">{{ page }}</a></li>
  {% else %}
  <li><a href="?{{ page.querystring }}" class="page">{{ page }}</a></li>
  {% endifequal %}
  {% else %}
  <li class="none"><a href="">...</a> </li>
  {% endif %}
  {% endfor %}

<!-- 判断是是否有下一页 -->
  {% if all_orgs.has_next %}
  <li class="long"><a href="?{{ all_orgs.next_page_number.querystring }}">下一页</a></li>
  {% endif %}
</ul>
</div>

最后的分页效果如下:

Django分页效果

导入导出

项目地址:https://github.com/django-import-export/django-import-export

$ pip install django-import-export

安装好之后,在settings.py引用即可:

settings.py

INSTALLED_APPS = [
    'import_export',  # 引用导入导出插件
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

接着可以直接在Django Admin后台引用:

admin.py

from import_export.admin import ImportExportActionModelAdmin

@admin.register(CourseOrg)
class CourseOrgAdmin(ImportExportActionModelAdmin):
    list_display = ['name', 'image_data', 'address']
    search_fields = ['name', 'city', 'address', 'desc']
    list_filter = ['city', 'add_time']

最后配合Simple UI的效果如下:

Simple UI 导入导出

Admin 配置

修改后台名称

在urls.py 里面添加 如下即可:

Python

admin.site.site_header = '后台管理'
admin.site.site_title = 'Django 后台管理'

核心原理就是 在引用 这个模块的文件里面添加配置即可生效:

from django.contrib import admin

最后效果如下:

Django自定义后台名称

图片显示

Django Admin 的列表中图片只显示 url 地址,却不能直接显示出来:

Django Admin图片不显示

解决方法就是重写Django Admin 后台图片的显示。

models.py

from django.utils.html import format_html

class CourseOrg(models.Model):
    image = models.ImageField(upload_to='org/%Y/%m', verbose_name='logo', max_length=100)

    # 定义 image_data 将 url 手动 通过 img 表情显示出来
    def image_data(self):
        return format_html(
            '<img src="{}" width="200px" height="90px"/>',
            self.image.url,
        )
        # 设置标题
    image_data.short_description = '图片'  

admin.py

from django.contrib import admin

@admin.register(CourseOrg)
class CourseOrgAdmin(admin.ModelAdmin):
      # 显示里面 传入 我们自定义的 image_data
    list_display = ['name', 'image_data', 'address']
    search_fields = ['name', 'city', 'address', 'desc']
    list_filter = ['city', 'add_time']

    # 设置该列不可编辑
    readonly_fields = ('image_data',)

最后显示效果如下:

Django Admin 图片显示
回复下方「关键词」,获取优质资源

回复关键词「 pybook03」,立即获取主页君与小伙伴一起翻译的《Think Python 2e》电子版
回复关键词「入门资料」,立即获取主页君整理的 10 本 Python 入门书的电子版
回复关键词「m」,立即获取Python精选优质文章合集
回复关键词「book 数字」,将数字替换成 0 及以上数字,有惊喜好礼哦~
题图:pexels,CC0 授权。

好文章,我在看
手册说明: Django教程简介 Django是一个可以使Web开发工作愉快并且高效的Web开发框架。 使用Django,使你能够以最小的代价构建和维护高质量的Web应用。 从好的方面来看,Web 开发激动人心且富于创造性;从另一面来看,它却是份繁琐而令人生厌的工作。 通过减少重复的代码,Django 使你能够专注于 Web 应用上有 趣的关键性的东西。 为了达到这个目标,Django 提供了通用Web开发模式的高度抽象,提供了频繁进行的编程作业的快速解决方法,以及为“如何解决问题”提供了清晰明了的约定。 同时,Django 尝试留下一些方法,来让你根据需要在framework之外来开发。 本教程的目的是将你培养成Django专家。 主要侧重于两方面: 第一,我们深度解释 Django 到底做了哪些工作以及如何用她构建Web应用;第二,我们将会在适当的地方讨论更高级的概念,并解释如何 在自己的项目中高效的使用这些工具。 通过阅读此书,你将学会快速开发功能强大网站的技巧,并且你的代码将会十分 清晰,易于维护。 本书的代码清晰,易维护,通过学习,可以快速开发功能强大的网站。 喜欢一个学习观点以教促学, 一直以来, 学习的时候经常会发现, 某个方法某个问题自己已经明白了, 但是在教给别人的时候确说不清楚, 所以慢慢的学会了以教促学这种方法, 在教给别人知识的同时也能够提升自己对语言, 对框架的理解. 希望达到的目标: 希望能写出一个系列文章, 我也不知道到底能写多少 能够让认真阅读这个系列的文章的人, 能在读完之后做出一个简单的博客 教会读者使用简单的git操作和github 希望能够加深自己对Django的理解 Django是python中目前风靡的Web Framework, 那么什么叫做Framework呢, 框架能够帮助你把程序的整体架构搭建好, 而我们所需要做的工作就是填写逻辑, 而框架能够在合适的时候调用你写的逻辑, 而不需要我们自己去调用逻辑, 让Web开发变的更敏捷. Django是一个高级Python Web框架, 鼓励快速,简洁, 以程序设计的思想进行开发. 通过使用这个框架, 可以减少很多开发麻烦, 使你更专注于编写自己的app, 而不需要重复造轮子. Django免费并且开源.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值