Django基础篇 07-Django后端和html交互

一、上下文管理器

context_processors 执行顺序是 先执行views.py中代码,在views返回之前在走到TEMPLATES.OPTIONS.context_processors的方法中

1.1、在应用./user下新增context_process.py文件 

 

from . import models
# 上下文管理器
def title_process(request):
    return {'title':'童玲的博客'}

def category_process(request):
    categories = models.Category.objects.all()
    return {'categories':categories}

def tag_process(request):
    tag_list = ['python','django','自动化测试']
    return {'tag_list':tag_list}
View Code

 

 

 

1.2、在工程的sky/settings.py下添加如下代码:

   'user.context_process.category_process',
   'user.context_process.tag_process',
    'user.context_process.title_process'
View Code

整个settings.py的代码为:

"""
Django settings for sky project.

Generated by 'django-admin startproject' using Django 3.2.6.

For more information on this file, see
https://docs.djangoproject.com/en/3.2/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.2/ref/settings/
"""
import os
from pathlib import Path

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-&9dmdfb5o_3ckyzo$s)b(-b37%x!f3l3jb7n+ukji5)$avh216'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = ['*']    #配置允许哪些ip访问的  *允许所有的


# Application definition

INSTALLED_APPS = [
    'simpleui',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'user',
    'order'
]  #app注册

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]   #中间件

ROOT_URLCONF = 'sky.urls'

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',
                'user.context_process.category_process',
                'user.context_process.tag_process',
                'user.context_process.title_process'
            ],
        },
    },
]  # 设置模板的 前后端不分离的时候它有用
# context_processors 执行顺序是 先执行views.py中代码,在views返回之前在走到TEMPLATES.OPTIONS.context_processors的方法中



WSGI_APPLICATION = 'sky.wsgi.application'


# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR,'db.sqlite3'),
    }
}  #配置数据库的地方 默认是sqlite3


# Password validation
# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/3.2/topics/i18n/

LANGUAGE_CODE = 'zh-Hans'  # 设置语言,'en-us':英文,'zh-Hans':中文

TIME_ZONE = 'Asia/Shanghai'    # 设置时区,'UTC':标准时区 格林威治时间,'Asia/Shanghai':亚洲上海时区

USE_I18N = True

USE_L10N = True

USE_TZ = False  # 设置是否使用标准时区时间,我们设置为False  不适用标准时区


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.2/howto/static-files/

STATIC_URL = '/static/'

# 设置静态文件目录
STATICFILES_DIRS = (
    os.path.join(BASE_DIR,'static'),
)

# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
View Code

二、后端和html交互、重定向例子

2.1 编写前端表单代码:

样式:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

    <form action="/add" method="post">
        {% csrf_token %}
        <div>title: <input name = "title"></div>
        <div>content: <input name = "content"></div>

        <select name="category_id">
            {% for category in categories %}
                <option value="{{ category.id }}">{{ category.name }}</option>
            {% endfor %}

        </select>
        <button type="submit">提交</button>
    </form>

</body>
</html>
View Code

 {% csrf_token %} 为可以保存django后端返回的csrf token值 或者注释掉:settings.py中MIDDLEWARE[

'django.middleware.csrf.CsrfViewMiddleware'

]

settings.py代码:

"""
Django settings for sky project.

Generated by 'django-admin startproject' using Django 3.2.6.

For more information on this file, see
https://docs.djangoproject.com/en/3.2/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.2/ref/settings/
"""
import os
from pathlib import Path

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-&9dmdfb5o_3ckyzo$s)b(-b37%x!f3l3jb7n+ukji5)$avh216'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = ['*']    #配置允许哪些ip访问的  *允许所有的


# Application definition

INSTALLED_APPS = [
    'simpleui',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'user',
    'order'
]  #app注册

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    # 'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]   #中间件

ROOT_URLCONF = 'sky.urls'

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',
                'user.context_process.category_process',
                'user.context_process.tag_process',
                'user.context_process.title_process'
            ],
        },
    },
]  # 设置模板的 前后端不分离的时候它有用
# context_processors 执行顺序是 先执行views.py中代码,在views返回之前在走到TEMPLATES.OPTIONS.context_processors的方法中



WSGI_APPLICATION = 'sky.wsgi.application'


# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR,'db.sqlite3'),
    }
}  #配置数据库的地方 默认是sqlite3


# Password validation
# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/3.2/topics/i18n/

LANGUAGE_CODE = 'zh-Hans'  # 设置语言,'en-us':英文,'zh-Hans':中文

TIME_ZONE = 'Asia/Shanghai'    # 设置时区,'UTC':标准时区 格林威治时间,'Asia/Shanghai':亚洲上海时区

USE_I18N = True

USE_L10N = True

USE_TZ = False  # 设置是否使用标准时区时间,我们设置为False  不适用标准时区


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.2/howto/static-files/

STATIC_URL = '/static/'

# 设置静态文件目录
STATICFILES_DIRS = (
    os.path.join(BASE_DIR,'static'),
)

# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
View Code

前端add_article.html代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

    <form action="/add" method="post">
{#        {% csrf_token %}#}
        <div>title: <input name = "title"></div>
        <div>content: <input name = "content"></div>

        <select name="category_id">
            {% for category in categories %}
                <option value="{{ category.id }}">{{ category.name }}</option>
            {% endfor %}

        </select>
        <button type="submit">提交</button>
    </form>

</body>
</html>
View Code

2.2 编写后端代码

views.py中添加视图函数:

from django.http import JsonResponse, HttpResponseRedirect
from django.shortcuts import render
from django.shortcuts import  HttpResponse
from django.shortcuts import get_object_or_404
from django.core.paginator import Paginator
def add_article(request):
    if request.method.upper() == 'GET':
        return render(request,'add_article.html')
    title = request.POST.get('title')
    content = request.POST.get('content')
    category_id = request.POST.get('category_id')
    models.Article.objects.create(title=title,content=content,category_id=category_id)
    return HttpResponseRedirect('/')
View Code

2.3 urls.py注册路由

from django.contrib import admin
from django.urls import path
from user import views

urlpatterns = [
    path('add',views.add_article)
]
View Code

三、ORM

/sky/user/models_test.py

import os,django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'sky.settings')
django.setup()

from user import models
from django.db.models import Q

"""
新增
"""
# 新增
models.Category.objects.create(name = 'Oracle')

c = models.Category(name='RabbitMQ')
c.save()

# 有外键的情况下 插入数据
models.Article.objects.create(title='orm学习',
                              content='orm学习,content'
                             ,read_count=1,
                              category_id=1)   # 指定外键

category = models.Category.objects.get(id =2)

models.Article.objects.create(title='orm学习',
                              content='orm学习,content'
                             ,read_count=1,
                              category_id=category.id)   # 指定外键

models.Article.objects.create(title='orm学习',
                              content='orm学习,content'
                             ,read_count=1,
                              category = category)   # 指定外键
"""
修改
"""
# 修改
# update user set name = 'tongling';
# update user set sex = 1 where age >19;

c = models.Category.objects.get(id = 1)
c.name = 'java'
c.save()            # 修改单条数据

models.Category.objects.all().update(name ='abc')       # 修改全表数据的某个字段

# 按照过滤条件修改一批数据的 某些字段值
models.Category.objects.filter(name='abc').update(name='cc',age=13)
"""
删除
"""
c = models.Category.objects.get(id = 1)
c.delete()      # 删除一条数据


# 删除全表数据
models.Category.objects.all().delete()

# 按照过滤条件删除一批数据
models.Category.objects.filter(id<5).delete()

"""
复杂的查询
"""
# 大于 小于 大于等于 in  not  小于等于 或

print(models.Article.objects.filter(read_count__gt=0))      # 大于
print(models.Article.objects.filter(read_count__gte=0))     # 大于等于
print(models.Article.objects.filter(read_count__lt=0))             # 小于
print(models.Article.objects.filter(read_count__lte=0))           # 小于等于
print(models.Article.objects.exclude(read_count=0))     # read_count != 0
print(models.Article.objects.filter(id__in=[1,2,3]))   # 在[1,2,3]中
print(models.Article.objects.filter(id=1).first())       # 查询出多条 取第一条
print(models.Article.objects.filter(title__contains='orm'))   # like包含某个字符串的查询方式
print(models.Article.objects.filter(title__icontains='ORM'))    # 忽略大小写 包含某个字符串的查询方式
print(models.Article.objects.filter(title__startswith='xxx'))  # 以xx开头的查询条件





"""
get()和 filter().first()的用法的比较,一般优先使用filter().first()
"""

models.Article.objects.get(id=1)    # 如果id不存在,查询无数据 则此条语句会报错 需要try expection ,可以考虑使用filter().first()代替

query_set = models.Article.objects.filter(id=80)
if query_set:
    article = query_set.first()         # 第一条
    query_set.last()        # 最后一条
else:
    print('这条数据不存在')


# read_count()>0 或者 title中包含orm的条件

query_set = models.Article.objects.filter( Q(read_count__gt=0) | Q(title__contains='orm'))
print(query_set)

print(models.Article.objects.filter(read_count__isnull=True))      #判断是否为null
print(models.Article.objects.filter(title =''))        # 判断是否为空字符串
View Code

 

四、分页

/sky/user/views.py 添加视图函数

 1 def index(request):
 2     articles = models.Article.objects.all()
 3     page_num = request.GET.get('page',1)
 4     limit = request.GET.get('limit',5)
 5     page = Paginator(articles,limit)        # 分页后的对象
 6     articles = page.page(page_num)          # 当前页的数据
 7 
 8     # print(articles.has_next())                  # 有没有下一页 有返回True 否则False
 9     # print(articles.next_page_number())          # 获取下一页的页码,如果没有下一页 则会报错
10     # print(articles.has_other_pages())           # 有没有其他页,有则True,否则False
11     # print(articles.has_previous())              # 有没有上一页,有则True, 否则False
12     # print(articles.previous_page_number())      # 获取上一页的页码
13     # print(articles.number)                      # 获取当前页的页码
14     # print(articles.start_index())               # 当前页第一条数据的下标
15     # print(articles.end_index())                 # 当前页最后一条数据的下标
16     # articles.paginator                          # 分页后的对象 相当于page
17     # print(page.num_pages)                       # 总共多少页
18     # print(page.page_range)                      # 分页的范围 1 2 3 4 5 ....
View Code

/sky/templates/index.html

 1     <div class="text-center mt-2 mt-sm-1 mt-md-0 mb-3 f-16">
 2         {%  if articles.has_previous %}
 3             <a class="text-success" href="?page={{ articles.previous_page_number }}">上一页</a>
 4         {% else %}
 5             <span class="text-secondary" title="当前页已经是首页">上一页</span>
 6         {% endif %}
 7 
 8         <span class="mx-2">第 {{ articles.number }}&nbsp;/&nbsp;{{ articles.paginator.num_pages }}&nbsp;页</span>
 9         {% if articles.has_next %}
10             <a class="text-success" href="?page={{ articles.next_page_number }}">下一页</a>
11         {% else %}
12             <a class="text-secondary" title="当前页已经是最后一页">下一页</a>
13         {% endif %}
14 
15     </div>
View Code

效果图:

 

 

 

 

 

posted @ 2021-12-26 20:55  捞铁  Views(442)  Comments(0Edit  收藏  举报