Django笔记 - duolabmeng6/pyefun GitHub Wiki

#这部分要使用cmd执行
#创建项目,会在CMD目录下创建项目文件夹
django-admin startproject 项目名

#下面这些需要把CMD切到项目文件夹里执行
#创建超级管理员
python manage.py createsuperuser

#新增APP
python manage.py startapp APP名称

#应用数据库
python manage.py migrate

#启动
python manage.py runserver
python manage.py runserver 0.0.0.0:8000    #自定义ip跟端口启动
#settings.py

#设置成中文,最下面的改成这个
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_L10N = True
USE_TZ = False


#开启,关闭调试模式
DEBUG = True #(True:开启,False:关闭)


#设置成所有ip都可以访问
ALLOWED_HOSTS = ['*']


#iframe不能加载,Django2没有这个问题,Django3需要添加这个
X_FRAME_OPTIONS = 'ALLOWALL'


#新添加APP后要来这里添加
INSTALLED_APPS = ['新app名']


#关闭csrf,我基本不用这个,使用这个表单提交的时候好像页面还要加个参数
# 在 MIDDLEWARE 内,屏蔽'django.middleware.csrf.CsrfViewMiddleware'

#设置html文件存放目录,修改TEMPLATES下面这个键值,templates为文件夹名可修改,要确保目录下有这个文件夹
TEMPLATES = ['DIRS': [os.path.join(BASE_DIR, "templates")]]


#设置资源文件位置,在调试跟非调试模式下要修改斜杠我也不知道为啥,反正改了就正常
STATIC_URL = '/static/'

STATICFILES_DIRS = [os.path.join(BASE_DIR, "static")]
#调试模式时(DEBUG = True)这里不带斜杠 反之

STATIC_ROOT = os.path.join(BASE_DIR, "/static/")
#调试模式时(DEBUG = True)这里带斜杠 反之
from django.conf.urls import url
from django.views import static
from django.conf import settings
from web import views as web #从我的web app引入处理函数

#设置资源文件(js,css,img等)都可以访问
urlpatterns = [
url(r'^assets/(?P<path>.*)$',static.serve,{'document_root':settings.STATIC_ROOT},name='static')
]


#403,404,500设置
handler403 = web.页面403 #web.xxx 是我设置的响应函数
handler404 = web.页面404
handler500 = web.页面500
#参考 web/views.py
def 页面403(request, exception, template_name='error\403.html'):
    return render(request, template_name, status=403)
类型 描述
exact 精确匹配: polls.get_object(id__exact=14).
iexact 忽略大小写的精确匹配: polls.objects.filter(slug__iexact="foo") 匹配 foo, FOO, fOo, 等等.
contains 大小写敏感的内容包含测试: polls.objects.filter(question__contains="spam") 返回question 中包含 "spam" 的所有民意测验.(仅PostgreSQL 和 MySQL支持. SQLite 的LIKE 语句不支持大小写敏感特性. 对Sqlite 来说, contains 等于 icontains.)
icontains 大小写不敏感的内容包含测试:
gt 大于: polls.objects.filter(id__gt=4).
gte 大于等于.
lt 小于.
lte 小于等于.
ne 不等于.
in 位于给定列表中: polls.objects.filter(id__in=[1, 3, 4]) 返回一个 polls 列表(ID 值分别是 1或3或4).
startswith 大小写敏感的 starts-with: polls.objects.filter(question__startswith="Would"). (仅PostgreSQL 和MySQL支持. SQLite 的LIKE 语句不支持大小写敏感特性. 对Sqlite 来说,startswith 等于 istartswith)
endswith 大小写敏感的 ends-with. (仅PostgreSQL 和 MySQL)
istartswith 大小写不敏感的 starts-with.
iendswith 大小写不敏感的 ends-with.
range 范围测试: polls.objects.filter(pub_date__range=(start_date, end_date)) 返回 pub_date 位于 start_dateend_date (包括)之间的所有民意测验
year 对 date/datetime 字段, 进行精确的 匹配: polls.get_count(pub_date__year=2005).
month 对 date/datetime 字段, 进行精确的 匹配:
day 对 date/datetime 字段, 进行精确的 匹配:
isnull True/False; 做 IF NULL/IF NOT NULL 查询: polls.objects.filter(expire_date__isnull=True).
#引入当前app的models用于操作,也可以引入其他app的
from . import models

#获取该表全部数据
models.表名.objects.all().values_list() #返回全部字段内容,列表格式
models.表名.objects.all().values_list('id','name') #只返回id跟name字段的内容,列表格式
models.表名.objects.all().values()

#查询
models.表名.objects.filter(id=1, status=1).values_list("user")
#筛选字段 id=1且 status=1,以列表格式返回匹配行的user字段

#筛选id=1的字段,如果不存在会报错
结果 = models.表名.objects.get(id=1)
结果.user #只匹配1条记录的时候,可以这样获取user的值
结果[0].user #匹配多条记录的时候

#获取id等于1的记录条数
models.表名.objects.filter(id=1).count()


#更新记录
models.表名.objects.filter(id=1).update(userid=2)
#更新id=1的userid值为2


#增加记录
models.表名.objects.create(id=1,userid=2)
#新增一条记录 id=1 userid=2


#删除记录
models.表名.objects.filter(id=1).delete()
#删除id=1的记录
#Django在字段上增加各种条件进行匹配,在字段后面加上双下划线跟类型名称

models.表名.objects.filter(id__in=[1,2,5]).values_list()
#筛选出id等于1跟2跟5的记录

models.表名.objects.filter(id__range=(1,5)).values_list()
#筛选出id在1跟5以内的记录

models.表名.objects.filter(name__icontains="陈a").values_list()
#忽略大小写的模糊搜索name字段包含 陈a 或 陈A 字的记录

models.表名.objects.filter(name__contains="陈a").values_list()
#匹配大小写的模糊搜索name字段包含 陈a 字的记录

models.表名.objects.filter(name__exact="陈a").values_list()
#精确匹配大小写,匹配name字段等于 陈a 字的记录

models.表名.objects.filter(name__iexact="陈a").values_list()
#忽略大小写,匹配name字段等于 陈a 或 陈A 字的记录

models.表名.objects.filter(id__gt=10).values_list()
#匹配id大于10的记录

models.表名.objects.filter(id__gte=10).values_list()
#匹配id大于等于10的记录

models.表名.objects.filter(id__lt=10).values_list()
#匹配id小于10的记录

models.表名.objects.filter(id__lte=10).values_list()
#匹配id小于等于10的记录

models.表名.objects.filter(id__ne=10).values_list()
#匹配id不等于10的记录

#更多方法:https://www.cnblogs.com/yifugui/p/8075306.html
#在settings.py同目录下新建 database_route.py,粘贴下面这段进去
from django.conf import settings

DATABASE_MAPPING = settings.DATABASE_APPS_MAPPING

class DatabaseAppsRouter(object):
    """
    A router to control all database operations on models for different
    databases.

    In case an app is not set in settings.DATABASE_APPS_MAPPING, the router
    will fallback to the `default` database.

    Settings example:

    DATABASE_APPS_MAPPING = {'app1': 'db1', 'app2': 'db2'}
    """

    def db_for_read(self, model, **hints):
        """"Point all read operations to the specific database."""
        if model._meta.app_label in DATABASE_MAPPING:
            return DATABASE_MAPPING[model._meta.app_label]
        return None

    def db_for_write(self, model, **hints):
        """Point all write operations to the specific database."""
        if model._meta.app_label in DATABASE_MAPPING:
            return DATABASE_MAPPING[model._meta.app_label]
        return None

    def allow_relation(self, obj1, obj2, **hints):
        """Allow any relation between apps that use the same database."""
        db_obj1 = DATABASE_MAPPING.get(obj1._meta.app_label)
        db_obj2 = DATABASE_MAPPING.get(obj2._meta.app_label)
        if db_obj1 and db_obj2:
            if db_obj1 == db_obj2:
                return True
            else:
                return False
        return None

    def allow_syncdb(self, db, model):
        """Make sure that apps only appear in the related database."""

        if db in DATABASE_MAPPING.values():
            return DATABASE_MAPPING.get(model._meta.app_label) == db
        elif model._meta.app_label in DATABASE_MAPPING:
            return False
        return None

    def allow_migrate(self, db, app_label, model=None, **hints):
        """
        Make sure the auth app only appears in the 'auth_db'
        database.
        """
        if db in DATABASE_MAPPING.values():
            return DATABASE_MAPPING.get(app_label) == db
        elif app_label in DATABASE_MAPPING:
            return False
        return None
#settings.py 做如下修改
#添加数据库信息
#项目里的数据库名自己定义,简单点就直接跟着数据库名用一样的,可以按下面这样添加多个数据库
DATABASES = {
    '项目里的数据库名1': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': '数据库名',
        'USER': '数据库用户名',
        'PASSWORD': '数据库密码',
        'HOST': '数据库连接地址',
        'PORT': '端口',
    },
    '项目里的数据库名2': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': '数据库名',
        'USER': '数据库用户名',
        'PASSWORD': '数据库密码',
        'HOST': '数据库连接地址',
        'PORT': '端口',
    }
}

#新增
DATABASE_ROUTERS = ['Django.database_router.DatabaseAppsRouter']

#设置指定app使用指定数据库
DATABASE_APPS_MAPPING = {
    'app1': '项目里的数据库名1',
    'app2': '项目里的数据库名2',
}
#app/__init__.py
import pymysql
pymysql.install_as_MySQLdb()

#每个app目录下的__init____.py都要加入这段才能正常使用
#把数据库里的字段信息导入app中
python manage.py inspectdb --database=项目里的数据库名1
python manage.py inspectdb --database=项目里的数据库名1> app1/models.py

#我一般都是自己在工具里弄好数据库表然后这样导入省事,导入后就可以在vivews.py文件里直接导入models.py文件操作数据库了

#当然也可以自己在models.py里创建数据库表然后再同步到数据库里,或者同步到Django自带的后台管理里,步骤太多参考百度吧
#settings.py 内添加

SESSION_CACHE_ALIAS = 'default'#设置存放的数据库,DATABASES里设置的数据库名,default为默认的
SESSION_COOKIE_NAME = "sessionid"  # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串
SESSION_COOKIE_PATH = "/"  # Session的cookie保存的路径
SESSION_COOKIE_DOMAIN = None  # Session的cookie保存的域名
SESSION_COOKIE_SECURE = False  # 是否Https传输cookie
SESSION_COOKIE_HTTPONLY = True  # 是否Session的cookie只支持http传输
SESSION_COOKIE_AGE = 604800  # Session的cookie失效日期(1周)
SESSION_EXPIRE_AT_BROWSER_CLOSE = False  # 是否关闭浏览器使得Session过期
SESSION_SAVE_EVERY_REQUEST = True #如果设置 True,在30分钟期间有请求服务端,就不会过期!

#详细参考:
#https://blog.csdn.net/qq_42716602/article/details/81974492
#https://www.cnblogs.com/zhuifeng-mayi/p/9099811.html
#html文件如要要使用静态资源
#HTML头部添加
{% load static %}
#调用
{% static '相对路径' %}

#html传参
{{ 参数名 }} #html文件里使用这种格式预留指定参数,render返回时可以通过字典方式传参进来

#获取post请求里name的值,如果不存在则为空
request.POST.get('name', '')
#获取get请求里name的值,如果不存在则为空
request.GET.get('name', '')

#使用sessions需要导入模块
from django.contrib.sessions.models import Session

#获取session里name的值,如果不存在则为空
request.session.get('name', '')
#设置,修改session里name的值
request.session['name'] = "昵称"

#只允许单独在线的话上线后把其他name一样的删除就掉线了
from django.contrib.sessions.models import Session
from django.utils import timezone
from django.db.models import Q

key = request.session.session_key #获取当前请求的session_key
for session in Session.objects.filter(~Q(session_key=key),expire_date__gte=timezone.now()):
    data = session.get_decoded()
    if data.get('user', None) == user:
        session.delete()



#返回一个网页
from django.shortcuts import render
return render(request, 'tpl/theme.html') #返回设置的网页文件目录下tpl文件夹里theme.html
return render(request, 'tpl/theme.html', status=500) #返回一个页面,返回的状态码为500

return render(request, 'tpl/theme.html', {"参数1":"aa"})
#返回一个页面,并给页面传参数,html文件里需要有 {{ 参数1 }} 接收参数

#302跳转到其他页面
from django.http import HttpResponseRedirect
return HttpResponseRedirect("home/") #跳转到url/home页面

#给网页返回Json数据
from django.http import HttpResponse
import json
message = {"id":10,"msg":"成功"}
return HttpResponse(json.dumps(message,ensure_ascii=False),content_type="application/json,charset=utf-8")


#限制只允许GET或POST方式访问,在响应的函数上添加指定装饰器
from django.views.decorators.http import require_GET, require_POST

@require_POST #只允许POST请求
def login(request):
    pass


#Django使用前端框架layui的时候会遇到 {{ 变量名 }}的冲突,因为两边都支持解析这种语法
#使用的时候用下面的格式就能正常使用了
#Django
{{ 变量名 }}
#Layui
{% verbatim %}{{ 变量名 }}{% endverbatim %}
⚠️ **GitHub.com Fallback** ⚠️