Django基础和安装

预装库
pip3 install django
pip3 install requests
pip3 install django-mathfilters #模板高级计算
pip3 install pycryptodome #福禄解密
pip3 install huey
pip3 install gevent
sudo apt-get install gettext #翻译套件

查看版本python3 -m django --version
创建一个名为mysite项目django-admin startproject mysite
然后打开mysite文件夹cd mysite
在项目下创建一个e名为myapp的程序python manage.py startapp myapp
设置settings.py 的INSTALLED_APPS添加:myapp,这样才能让myapp生效
添加MEDIA_ROOT = 'static/' #添加静态目录,响应静态

将app路由添加进主项目

修改项目文件mysite/urls.py:

from django.contrib import admin
from django.urls import path,include

#如果设置了根路由就是myapp,则规则都需要写到myapp/urls.py中
urlpatterns = [
    path("myapp/", include("myapp.urls")),  #将myapp的路由添加进去
    path('admin/', admin.site.urls),
]
添加路由

修改myapp/urls.py,添加一个路由

from django.urls import path

from . import views

urlpatterns = [
    path("", views.index, name="index"),  #这里的index路由和视图的函数对应
    path("ceshi/<int:qq>/<str:yy>", views.ceshi, name="ceshiname"),  
    #ceshi是路由面是参数和定义参数类型,views.ceshi是视图对应的处理函数,name是方法名称,在模板中使用{% url %}时使用
]
添加视图

修改myapp/views.py,设置视图

from django.http import HttpResponse
from django.shortcuts import render
from .models import Question

def index(request):
    return HttpResponse("这里是视图文件")

def ceshi(request,qq,yy): #后面的qq,yy是路由传入的参数
    jieguo = Question.objects.all()
    #django的任何变量传递都要通过字典
    return render(request, 'index.html', {'jieguo': jieguo,'qq': qq, 'yy': yy})
模板文件
{% if jieguo %}
    <ul>
    {% for question in jieguo %}
        <li><a href="{% url 'ceshiname' question.id '2' %}">{{ question.question_text }}</a></li>
    {% endfor %}
    </ul>
{% else %}
    <p>没有这个项目</p>
{% endif %}

<p>显示静态内容</p>
{% load static %}
    {% for aa in jieguo %}
    <img src="{% static aa.icon %}">
    <br>
     {{aa.biaoti}}
     <br>
     {{aa.neirong}}
    {% endfor %}

<p>临时赋予变量某个值</p>
{% with name="哈哈" %}
{{ name1 }}
{% endwith %} 

运行测试服务器 python manage.py runserver 80

mysite/settings.py 程序设置

INSTALLED_APPS #激活的django组件
LANGUAGE_CODE #程序语言 简体中文'zh-hans'英语'en-us'
ROOT_URLCONF #设置根路由例如'myapp.urls'
DATABASES #配置数据库
添加 AUTH_USER_MODEL = 'myapp.User' #如果你 有自定义用户数据库的话

TIME_ZONE #时区默认UTC,'Asia/Shanghai' 北京时区

STATIC_URL = 'static/' #静态文件路由

MEDIA_ROOT = 'static/' #上传媒体路径这里它会自动加上uploads
ALLOWED_HOSTS = ['c.3kj.online'] #允许的域名,多个域名就添加多个

数据库操作

数据库创建与迁移

创建模型编辑myapp/models.py:

from django.db import models
from django.contrib.auth.models import AbstractUser


class User(AbstractUser):  #继承自标准用户模型AbstractUser
    USERNAME_FIELD = 'email'  #设置email字段为认证字段,源代码中是使用username
    REQUIRED_FIELDS = []  #设置必填字段,源码里有email,所以这里必须要重新设置删除email
    last_name = None  #禁用字段
    first_name = None
    email = models.EmailField(_("邮箱"),unique=True,help_text=_('输入您的邮箱'))
    username = models.CharField(_("称呼"),max_length=150,help_text=_('我们如何称呼您?'))
    yue = models.DecimalField(max_digits=25, decimal_places=15,default=0.00)
    yaoqingma = models.CharField(max_length=12,unique=True)
    beiyaoqing = models.CharField(_("邀请码"),max_length=12,null=True,blank=True,help_text=_("如果您有邀请码请填写,您也可以不填写"))  #被邀请
    fanxian = models.BooleanField(default=True)  #是否符合返现
    is_email = models.BooleanField(default=False)  #是否完成邮箱认证


class Ceshi(models.Model):
    biaoti = models.CharField(max_length=200)
    neirong = models.TextField(blank=True)  #blank=True允许留空,不指定则默认必填
    icon = models.ImageField(upload_to='uploads/%Y/%m/%d/',blank=True)  #上传图片附件,并指定路径
    date = models.DateTimeField("发布日期") #这是一个提醒文字

    def __str__(self):
        return self.biaoti

编辑mysite/settings.py,为INSTALLED_APPS添加myapp:"myapp.apps.MyappConfig",

撤销之前迁移:python manage.py migrate myapp zero #如果之前有过迁移记录就删除
反撤销python manage.py migrate myapp

#创建数据库迁移python manage.py makemigrations
#服务器上报错请加python3

#迁移某个应用 python3 manage.py makemigrations myapp

#创建空迁移文件python manage.py makemigrations --empty myapp
如果发现可创建空迁移文件后,再将要修改的写入空文件中,确保修改后的和在模型设定中一一致

就会看到这个文件myapp/migrations/0001_initial.py #这将是要迁移的数据表

执行python manage.py sqlmigrate myapp <000>可以查看将要执行的sql语句

执行迁移数据库 python manage.py migrate #这将执行数据库修改或创建

如果修改了数据库表结构,且表中有数据,在创建迁移时会提示:
选项1,提供默认值,选择此项后输入对非空值的默认值即可
选项2,手动指定值

管理员账户

python manage.py createsuperuser 创建管理员,输入用户名,邮箱,重复两次密码
python manage.py changepassword <username> 修改管理员密码

在myapp/admin.py中将创建的数据库添加给管理员

from django.contrib import admin
from .models import Question

admin.site.register(Question)
全局隐式传入变量

在应用目录下新建一个gongxiang.py

from django.conf import settings

def languages_context(request):
    return {'LANGUAGES': settings.LANGUAGES}  #指定返回了LANGUAGES变量

在mysite/settings.py的TEMPLATES项中添加
'myapp.gongxiang.languages_context', #将返回变量传入全局
#这样就可以在所有模板中使用LANGUAGES变量了

从请求中取用户信息并修改数据库

def index(request):
    user = request.user  #通过请求信息获取用户对象
    #通过对象查询数据库
    user = get_object_or_404(User, pk=current_user.pk)
    user.is_email = True
    user.save()
    return HttpResponse('Success', status=200)

消息闪现message搭配bulmaCSS框架和bulma-toast.js

视图

from django.contrib import messages

def ceshi(request,diqu):
    #extra_tags是class样式,is-primary青色,is-success绿色,is-danger红色,is-warning黄色,可以附加is-light为上面颜色的浅色
    #messages会自动传递给请求,无需显示传递给模板
    messages.info(request, _("这是测试消息提示"),extra_tags="is-success")
    return render(request, 'ceshi.html')

因为消息闪现可能在所有页面都要使用,所以在layout.html模板中采用导入flask.html,还有个好处就是导入才会使用闪现的js

{% if messages %}
{% include 'flash.html' %}
{% endif %}

然后在flash模板中使用

<script src="bulma/bulma-toast.min.js"></script>
<script>
    //下面是刷新就触发
    window.onload = function () {
        bulmaToast.setDefaults({  //初始化设置
        duration: 3500,  //持续3.5秒
        position: 'top-center',  //顶部居中位置
        dismissible: true,  //显示关闭按钮
        })
        {% for message in messages %}
        //发布消息,{{ message }}是视图传递的内容,{{ message.extra_tags }}是class样式,也就是bulma样式
        bulmaToast.toast({ message: '{{ message }}', type: '{{ message.extra_tags }}' })  
        {% endfor %}
    }
</script>

设置cookie和session

cookie

#设置cookie
response = HttpResponse(status=200)
response.set_cookie('ck', 'all')  #名称,内容
#删除cookie
response.delete_cookie('forgot_password_email')
#将cookie处理信息返回给浏览器
return response


#模板中读取cookie
email = request.COOKIES.get('forgot_password_email') 

session

from datetime import timedelta
from django.utils import timezone

#设置session
request.session['forgot_password_email'] = email

#生成一个失效时间,20分钟,或者timedelta(hours=1)小时
expiration_time = timezone.now() + timedelta(minutes=20)
#设置刚刚的session过期时间
request.session.set_expiry(expiration_time)


#读取session
email = request.session.get('forgot_password_email')

#删除session
del request.session['forgot_password_email']

#浏览器读取session
{{ request.session.forgot_password_email }}

自定义权限装饰器

#自定义判断用户邮箱是否已验证装饰器
def is_email_required(view_func):
    @wraps(view_func)
    def _wrapped_view(request, *args, **kwargs):
        user = request.user
        if user.is_email:
            print('邮箱已验证')
            # 如果用户已登录且邮箱已验证,允许访问视图
            return view_func(request, *args, **kwargs)
        else:
            print('邮箱未验证')
            return redirect('/jump?next=active')  #定向到验证页面
    return _wrapped_view

直接返回字符串

return HttpResponse("This is a GET request.")