Django学习笔记
1、安装django
pip install -U django #安装django
2、创建django工程、启动工程
创建项目
django-admin startproject django_test
#安装完django后会有django-admin命令
#django_test是项目名称,创建项目时修改为自己的项目名称即可
启动项目
项目创建完成后,会在执行命令的目录下产生一个项目同名的目录,进入到这个项目执行命令就可以启动了,命令如下:
cd django_test
python manage.py runserver #启动工程,默认端口号8000
启动后访问 127.0.0.1:8000 即可看到django初始页面,如下图:
3、django目录说明
4、初始化配置
项目创建好后,有一些初始化的配置需要修改,在setting.py中
下面是要默认的配置
# LANGUAGE_CODE = 'en-us'
#默认语言 # TIME_ZONE = 'UTC'
#当前时区 # USE_TZ = True
#是否使用默认时区
#修改为下面的配置
LANGUAGE_CODE = 'zh-Hans' #中文
TIME_ZONE = 'Asia/Shanghai' #亚洲的时区
USE_TZ = False #不使用默认是时区
修改完成后,再刷新前面的初始化页面,可以看到都是中文的了。
如果要使用mysql数据库,除了修改setting文件中的配置外,还需要在和setting文件同目录下的__init__.py文件中配置如下内容:
import pymysql
pymysql.install_as_MySQLdb()
5、创建app
我们在写业务代码时,一般按照业务/工程划分模块,所以在写代码之前要先创建好一个模块,在django里面称为application,也就是app,命令如下:
python manage.py startapp user #创建一个user模块
注意:创建完app后,一定要在settings中的INSTALLED_APPS中配置上这个app
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'user', #新创建的app ]
创建完在工程目录下就多了一个user的目录,结构如下:
6、编写第一个view
接下来就可以编写第一个view了, 也就是我们的业务代码,在user里面的views.py里面定义一个函数,代码如下:
from django.http.response import HttpResponse
#导入HttpResponse,如果要返回一个字符串的话,要用HttpResponse才可以
def index(request): # request这个参数是必须要写的
msg = "hello world!"
return HttpResponse(msg)
7、配置urls
逻辑写完之后,客户端需要通过url来访问,就需要在urls里面配置上映射,配置一个url来对应上面写的index
from django.contrib import admin
from django.urls import path
from user import views
#从user模块中导入views
urlpatterns = [
path('admin/', admin.site.urls),#默认的配置,是django后端管理的
path('index', views.index),#这个是新配置的,url是index,访问这个url后就找到了前面写的index函数
]
8、测试view
访问 http://127.0.0.1:8000/index,可以看到访问到了前面写的view,展示了hello world
9、初始化命令总结
django-admin startproject project_name #创建项目
python manage.py startapp app_name #创建app
python manage.py runserver #启动项目
python manage.py runserver 8999 #指定端口号启动 只能本机访问
python manage.py runserver 0.0.0.0:8999 #别人通过你的IP地址也可以访问
10、静态文件配置
静态文件配置需要中setting文件中增加如下配置:
STATICFILES_DIRS = (os.path.join(BASE_DIR,'static'),)#静态文件目录
配置完成后,需要注意修改templates中的html里的静态文件地址,需要和配置相对应
11、生成表结构
需要在models文件中创建相应的类,例子如下:
from django.db import models
class Article(models.Model):
title = models.CharField(verbose_name='文章标题',max_length=100,db_index=True)
desc = models.CharField(verbose_name='描述',max_length=100,blank=True,null=True,default='这个文章没有描述')
content = models.TextField(verbose_name='文章内容')
img = models.ImageField(verbose_name='文章图片',upload_to='article_img',default='images/1.jpg') # pip install pillow article_img/%Y/%m settings里设置上传地址
recommend = models.BooleanField(verbose_name='是否推荐',default=False)
category = models.ForeignKey(Category,verbose_name='分类',on_delete=models.DO_NOTHING,db_constraint=False)
# models.CASCADE #级联删除 # db_constraint 不会真正在数据库里面建立外键
create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
update_time = models.DateTimeField(verbose_name='修改时间', auto_now=True)
is_deleted = models.BooleanField(verbose_name='是否删除', default=False)
class Meta:
db_table = 'article' #数据库中的表名称
ordering = ['create_time'] #排序
verbose_name = '文章'
verbose_name_plural = verbose_name #设置之后在后台可以按verbose_name显示
def __str__(self):
return self.title #查询结果在后台按title显示
类创建完成后需要再通过命令行执行下面两个命令
python manage.py makemigrations
python manage.py migrate
12、views查询数据
例子如下
from django.shortcuts import render,HttpResponse,get_object_or_404,Http404
from .models import Category,Article
from django.core.paginator import Paginator
from . import const
# Create your views here.
def index(request):
# catagories = Category.objects.filter(is_deleted=False)
category_id = request.GET.get('category_id',1)
page = request.GET.get('page',1)
limit = request.GET.get('limit',const.page_size)
article = Article.objects.filter(is_deleted=False,category_id=category_id)
page_obj = Paginator(article,limit)
page_data = page_obj.page(page)
# data = {'nav':catagories,'articles':article}
data = {'articles':page_data}
return render(request,'index.html',data)
13、后台管理
1、执行下面的命令创建超级管理员账号
python manage.py createsuperuser
根据提示填写相关内容,完成后可以登录Django的后台管理页面
14、orm单表增删改查
示例代码如下,创建一个文件,和model文件同级
import django,os
os.environ.setdefault('DJANGO_SETTINGS_MODULE','dj_test.settings')
django.setup()
from user.models import Category,Article
#增加
c_obj = Category.objects.create(name="Mysql")
print(c_obj.name)
print(c_obj.create_time)
print(c_obj.update_time)
obj = Category(name='Oracel')
obj.save()
#查询
print(Category.objects.all())
print(Category.objects.get(id__gt=1)) #get() returned more than one Category -- it returned 4!
print(Category.objects.get(name="Mysql"))
print(Category.objects.get(name="Linux"))
print(Category.objects.filter(id__gte=1))
print(Category.objects.filter(id__gte=1,name="Linux"))
print(Category.objects.exclude(name="Linux").filter(id__gt=3))
#修改
Category.objects.update(name="xxx")
Category.objects.update(is_deleted=True)
obj = Category.objects.get(id=1)
obj.is_deleted = False
obj.save()
Category.objects.filter(id__in=[2,3,4]).update(is_deleted=False)
#删除
Category.objects.all().delete()
obj = Category.objects.get(id=1)
obj.delete()
obj.save()
Category.objects.filter(id__in=[2,3,4]).delete(is_deleted=False)
15、上传文件
上传文件需要在setting文件中配置如下参数
MEDIA_ROOT = os.path.join(BASE_DIR,'static')#上传文件默认存放路径
然后结合model类中的upload_to字段结合形成最终上传地址
img = models.ImageField(verbose_name='文章图片',upload_to='article_img',default='images/1.jpg') # pip install pillow article_img/%Y/%m settings里设置上传地址
最终上传地址目录如下图
16、实现分类页面
原来是通过category去访问的方式实现查看分类页面的,后续优化代码的时候将可以合并的地方都合并了,可以参考index的代码,这里只是展示之前的实现方式
在url中配置
urlpatterns = [
path('admin/', admin.site.urls),
path('index/', index),
path('', index),
# path('category/<int:id>', category),
path('detail/', detail,name='detail'),
]
在view中配置
def category(request,id):
# catagories = Category.objects.filter(is_deleted=False)
article = Article.objects.filter(is_deleted=False,category_id=id)
# data = {'nav':catagories,'articles':article}
data = {'articles':article}
return render(request,'index.html',data)
这种方式是需要通过/id的方式去访问的,和之后的实现方式要区别开来。
17、上下文管理器
1、每个view里面都需要用到的操作,可以放到上下文管理器里面查
2、先定义一个函数,函数必须有一个参数request
3、这个函数要返回一个字典
文件和models文件在同一目录下,名字是process_content.py
from . import models
def category_process(request):
categories = models.Category.objects.filter(is_deleted=False)
return {'nav':categories}
# return locals() 如果不想规定返回的字典的key,可以用这种方式
4、要在配置文件里面配置,在TEMPLATES的OPTIONS中增加这个函数user.process_content.category_process
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',
'user.process_content.category_process',
],
},
},
]
18、模板继承
1、一些公用的html代码可以放在一个模板文件中,并在与其他html文件有区别的地方用代码标记,一遍有content、js和css
{% block css %}
{% endblock %}
{% block content %}
{% endblock %}
{% block js %}
{% endblock %}
2、在其他html文件中引用这个模板,需要在代码中加入extends声明引入的模板文件,并且在对应的模板位置引入不同代码
{% extends 'base.html' %}
{% block css %}
<link href="/static/css/info.css" rel="stylesheet">
{% endblock %}
{% block content %}
<article> 。。。。。。。
</article>
{% endblock %}
上面的例子中article的内容就是该html文件特有的内容,其作为content内容填充到模板标记的content位置。
19、分页
分页的后端方法如下
from django.core.paginator import Paginator
l = range(1,51)
page_obj = Paginator(l,10)
page_obj = Paginator(Article.objects.all(),2)
print(page_obj.page(1)) #取某一页数据
print(list(page_obj.page(3)))
print(list(page_obj.get_page(1)))
print(page_obj.count) #总共多少条
print(page_obj.num_pages) #共分了几页
print(page_obj.page_range) #分页的范围
cur_page = page_obj.page(2)
print(cur_page.has_previous()) #判断有没有上一页
print(cur_page.previous_page_number()) #获取上一页的页码
print(cur_page.has_next()) #判断有没有下一页
print(cur_page.next_page_number()) #获取下一页的页码
print(cur_page.has_other_pages()) #是否有其他页
print(cur_page.paginator)
分页的前端方法如下
{% if articles.has_other_pages %}
<div class="pagelist">
{% if articles.has_previous %}
<a class="allpage" href="/index?page={{ articles.previous_page_number }}&limit=10"><b>上一页</b></a>
{% endif %}
{% for page_num in articles.paginator.page_range %}
<a href="/index?page={{ page_num }}&limit=10" >{{ page_num }}</a>
{% endfor %}
{% if articles.has_next %}
<a href="/index?page={{ articles.next_page_number }}&limit=10" >下一页</a>
{% endif %}
</div>
{% endif %}
里面特色的地方在于page_range不是当前页的属性,而是分页对象的属性,所以需要通过paginator字段来获取分页对象,articles.paginator.page_range
20、优化和丰富Django admin
在admin文件中配置如下内容,可以在后台展示更多的字段和增加搜索、过滤、分页等功能
from django.contrib import admin
from . import models
# Register your models here.
class ArticleAdmin(admin.ModelAdmin):
list_display = ['title','category','create_time','update_time'] #显示哪些字段
search_fields = ['title'] #以哪些字段搜索,不要写外键
list_filter = ['category','is_deleted'] #以哪些字段过滤
list_per_page = 10 #分页,每页显示多少条
class CategoryAdmin(admin.ModelAdmin):
list_display = ['name','create_time','update_time'] #显示哪些字段
search_fields = ['name'] #以哪些字段搜索,不要写外键
list_filter = ['is_deleted'] #以哪些字段过滤
list_per_page = 10 #分页,每页显示多少条
class MyAdminSite(admin.AdminSite):
site_header = 'xxx后台管理'
site_title = 'xxxx后台管理'
# site = MyAdminSite()
# site.register(models.Category,CategoryAdmin)
# site.register(models.Article,ArticleAdmin)
admin.site.register(models.Category,CategoryAdmin)
admin.site.register(models.Article,ArticleAdmin)
如果想使用新的UI界面,可以通过下面的命令安装
pip install simpleui
然后在setting中配置simpleui
INSTALLED_APPS = [
'simpleui',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'user.apps.UserConfig',
]
21、前端自定义标签
该应用应包含一个 templatetags 目录,与 models.py, views.py 等同级。若该目录不存在,创建它——不要忘了用 __init__.py 文件确保目录被视作一个 Python 包。
开发服务器并不会自动重启 添加 templatetags 模块后,你需要重启服务器,这样才能在模板中使用 tags 和 filters。
自定义的 tags 和 filters 会保存在模块名为 templatetags 的目录内。模块文件的名字即稍候你用来加载 tags 的名字,所以小心不要采用一个可能与其它应用自定义的 tags 和 filters 冲突的名字。
在模板中你会使用以下代码:
{% load poll_extras %}
为了使 {% load %} 标签生效,包含自定义标签的应用必须包含在 INSTALLED_APPS 中。这是个安全特性:它允许你在一个主机上持有多个模板库,而不是让每个 Django 安装都能访问所有的库。
要成为一个可用的 tag 库,模块必须包含一个名为 register 的模块级变量,它是一个 template.Library 实例。所有的 tags 和 filters 均在其中注册。所以,在模块的开始,输入以下内容:
from django import template
register = template.Library()
my_tag示例
from django import template
register = template.Library()
@register.filter #最多就2个参数
def jieduan(s):
if len(s)>10:
s = s[:11]+'...'
return s
@register.simple_tag #不限制参数
def jieduan2(s,):
if len(s)>20:
s = s[:21]+'...'
return s
作用是截断过长的字符串,在html文件中需要下面这样使用
<p>{{arcl.desc | jieduan:20}}</p> #该方式最多有两个参数,第一个在|之前,第二个参数在函数之后
<p>{% jieduan2 arcl.desc 20%}</p> #该方式不限制参数数量,具体参考tag示例
Django自带的一些tag用法
例如设置时间的格式,可以直接使用|date:参数来设置,参考info页面
<li class="timer">{{ article.create_time|date:'Y-m-d D'}}</li>
<p>{{ h1_str| safe}}</p>
{#xss注入#}
#可以防止xss注入,例子参考视频,加上safe之后,浏览器会按照html标签来解析,不加的时候不会按html标签来解析。
22、form
待续