Django笔记
一次只打开一次服务
web服务器:负责处理http请求,响应静态文件,常见的有 Apache , Nginx
M :代表模型(Model),即数据存取层。 该层处理与数据相关的所有事务: 如何存取、如何验证有效
T :代表模板(Template),即表现层。 该层处理与表现相关的决定: 如何在页面或其他类型文档中进行显示。
V :代表视图(View),即业务逻辑层该层包含存取模型及调取恰当模板的相关逻辑。 你可以把它看作模型与模板之间的桥梁。

Django请求的生命周期
通过URL对应关系匹配 ->找到对应的函数(或者类)->返回字符串(或者读取Html之后返回渲染的字符串)
启动
进入到虚拟环境 workon django-env
想要在其他电脑上也能访问本网站,那么需要指定 ip 地址为 0.0.0.0
创建应用(app):一个项目类似于是一个架子,但是真正起作用的还是 app 。
python manage.py startapp [app名称]
使用 pycharm 创建完项目后,还是需要重新进入到命令行单独创建 app 的。
视图
视图一般都写在 app 的 views.py 中。并且视图的第一个参数永远都是 request (一个
HttpRequest)对象。
from django.http import HttpResponse
def book_list(request):
return HttpResponse("书籍列表!")
path('book/',views.book) #book后面无()执行这个函数 有就是函数执行的结果放进去
text = "您输入的书籍的id是:%s" % book_id #注意是%s不然传不进去
book_id = request.GET.get("id")
book_id = request.GET['id'] #不建议使用,可能是错的
![]()
reverse反转

应用命名空间
在view上反转:从urls上引进来的
urls.py
app_name='front' #加了命名空间views.py上没有就报错:NoReverseMatch at /
urlpatterns = [
path('login/',views.login,name='login'), #在url中取名字
]
views.py
from django.shortcuts import redirect,reverse
login_url=reverse('front:login')
return redirect(login_url)
INSTALLED_APPS=[] #已经安装的app 33
'APP_DIRS': True, #在其他的app中寻找
<li><a href="{% url 'book' %}">读书</a></li>
<li><a href="{% url 'detail' book_id='1' category=1 %}">最火的一篇文章</a></li>
<li> <a href="{% url 'login' %}?next=/"> 登录</a></li>
过滤器
cut
{{ 'valude dsa'|cut:" " }} #删除空格
date
# 数据
context = {
"birthday": datetime.now()
}
\# 模版
{{ birthday|date:"Y/m/d" }}
加载静态文件
1挂钩
static中新建一个文件夹与父文件夹名字保持一致
2不想重复加载就可以使用static
{% load static %}
<link rel="stylesheet" href="{% static 'style.css' %}">

TEMPLATES/OPTIONS #添加 52 'builtins': ['django.templatetags.static'] #以后在模版中就可以直接使用 static 标签
!!!前端的什么样式一股脑放在当前项目的static文件下面然后link
STATICFILES_DIRS = [ #在setting最后一行添加 os.path.join(BASE_DIR,"static") ]
数据库
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'django',
'USER':'root',
'PASSWORD':'1234',
'HOST':'127.0.0.1',
'POST':'3306',
}
}
pymysql连接数据库
import pymysql
db = pymysql.connect("localhost", "root", "1234", "django")
cursor = db.cursor() # 使用 cursor() 方法创建一个游标对象 cursor
cursor.execute("SELECT * from user") # 使用 execute() 方法执行 SQL 查询
data = cursor.fetchall() # 使用 fetchone() 方法获取单条数据.
db.close() # 关闭数据库连接
cursor.execute("insert into book(id,name,author) values(null,'%s','%s')" % (name,author))
插入获取的数据:
name = request.POST.get("name")
author = request.POST.get("author")
cursor.execute("insert into book(id,name,author) values(null,'%s','%s')" % (name,author))
连接数据库: 垃圾mysqlclient __init__中
import pymysql pymysql.install_as_MySQLdb()
LANGUAGE_CODE = 'zh-hans' TIME_ZONE = 'Asia/Shanghai'
sqlite的导出
python manage.py dumpdata > data.json
MySQL导入数据
python manage.py loaddata data.json
ORM
一个表一个模型 表当中有多少个字段在模型中就有多少个属性
返回想要打印的字段
models.py
def __str__(self):
# <Book:(name,author,price)>
return "<Book:({name},{author},{price})>".format(name=self.name,author=self.author,price=self.price)
format格式化函数:
"{1} {0} {1}".format("hello", "world") # 设置指定位置 #'world hello world'
查找
views.py中
根据id的方式进行查找
from .models import Book book = Book.objects.get(pk=1) #pk主键 #book = Book.objects.first() print(book)
根据其他条件进行查找
books = Book.objects.filter(name='三国演义').first() #filter过滤器 frist第一个值 返回Book类型
查询方式
.query 查询最终被翻译成的sql语句 再filter中使用,返回的是一个数据集
query 只能被用在QuerySet对象上
exact
article = Article.objects.get(id__exact=14) #__exact写不写都一样 大小写不敏感
iexact: 使用 like 进行查找。
contains: 大小写敏感,判断某个字段是否包含了某个数据。 加了binary 有%
icontains: 大小写不敏感的匹配查询。
F表达式:优化 ORM 操作数据库的
Employee.object.update(salary=F("salary")+1000) #相等 直接操作
authors = Author.objects.filter(name=F("email")) #不等,判断是否相等
Q表达式:要查询所有价格低于10元,或者是评分低于9分的图书。
from django.db.models import Q books = Book.objects.filter(Q(price__lte=10) | Q(rating__lte=9))
聚合函数:
from django.db.models import Avg,Count,Max,Min,Sum,F,Q
result = Book.objects.aggregate(avg=Avg('price'))
# print(connection.queries) 打印语句
获取图书和作者的名字
books = Book.objects.annotate(author_name=F("author__name"))#不是annotate顶多获取作者id
for book in books:
print('%s/%s' % (book.name,book.author_name)) #比author.name效率高
链式调用
filter :将满足条件的数据提取出来 exclude :排除满足条件的数据
books = Book.objects.filter(id__gte=2).exclude(id=3) #.filter(~Q(id=3))
添加,删除,修改
a= request.POST['name']
book = Book(name='西游记',author='吴承恩',price=100) book.save()
book = Book.objects.get(pk=1) #先获取 book.delete()
book = Book.objects.get(pk=2) book.price = 200 book.save()
模型常用属性:
CharField:必须 要指定最大的长度
title = models.CharField(max_length=200)
TextField: 大量的文本类型。映射到数据库中是longtext类型。
BooleanField: 在模型层面接收的是 True/False 。在数据库层面是 tinyint 类型。
removed = models.NullBooleanField() #可为空
FloatField: 浮点类型。映射到数据库中是 float 类型。
UUIDField: 只能存储 uuid 格式的字符串。 uuid 是一个32位的全球唯一的字符串,一般用来作为主键。
外键
父类影响子类
category =models.ForeignKey cascade
("Category",on_delete=models.CASCADE,null=True,related_name='articles')
author = models.ForeignKey("frontuser.FrontUser",on_delete=models.CASCADE,null=True)
class Comment(models.Model):
content = models.TextField()
origin_comment = models.ForeignKey("Comment",on_delete=models.CASCADE)
"Comment" "article.Comment" "self" #引用自身的三种方式
user = User.objects.first() # 获取第一个用户写的所有文章 23 articles = user.article_set.all() #子类名小写加_set 或者再models.py中创建数据库时#related_name='articles' == articles_set
死循环:
解决,并且自动保存了 使用bulk参数
pycharm小工具
直接输入,不需要python manage.py makemigrations
startapp name 创建新项目
makemigrations 迁移脚本的生成
migrate 将迁移脚本文件映射到数据库中
更改表名(创建表的过程中)models.py
连接数据库url后加: ?serverTimezone=UTC
ctrl+w 选中一个,在按再选中一个
表单
froms.py中
from django import forms
class MesssageBoardForm(forms.Form):
title = forms.CharField(max_length=100,min_length=2,label='标题',error_messages={"min_length":"最少不能少于1个字符!"})
content = forms.CharField(widget=forms.Textarea,label='内容',error_messages={"required":"必须要传content字段!"})
email = forms.EmailField(label='邮箱',error_messages={"required":'必须要传email字段!'})
reply = forms.BooleanField(required=False,label='是否回复')
views.py中
from django.shortcuts import render
from django.views.generic import View
from .forms import MesssageBoardForm
from django.http import HttpResponse
from django.forms.utils import ErrorDict #无用,查看get_json_data()的
class IndexView(View):
def get(self,request):
form = MesssageBoardForm() #空表单
return render(request,'index.html',context={"form":form})
#打印返回的数据
def post(self,request):
form = MesssageBoardForm(request.POST)
if form.is_valid():
title = form.cleaned_data.get('title')
content = form.cleaned_data.get('content')
email = form.cleaned_data.get('email')
reply = form.cleaned_data.get('reply')
print('='*30)
print(title)
print(content)
print(email)
print(reply)
print('='*30)
return HttpResponse('success')
else:
print(form.errors.get_json_data())
return HttpResponse('fail')
urls.py中
from django.urls import path
from front import views
urlpatterns = [
path('', views.IndexView.as_view()),
]
html中
<form action="" method="post"> #form中action留空 指定当前页面的url
<table>
{{ form.as_table }} #自动生成
<tr>
<td></td>
<td><input type="submit" value="提交"></td>
</tr>
</table>
</form>
验证器:
class MyForm(forms.Form):
telephone = forms.CharField(validators=[validators.RegexValidator("1[345678]\d
{9}",message='请输入正确格式的手机号码!')])
项目
项目代码
概念
-
nvm(version):管理node.js的工具
-
node.js自带有npm包管理工具
-
npm(package):类似python的pip
-
gulp:压缩
操作
下载nvm
https://github.com/coreybutler/nvm-windows/releases nvm-setup.zip
nvm常用命令
-
nvm install node 最新
-
nvm install version 指定
-
nvm use version 使用
-
nvm list 列出
-
nvm uninstall version 卸载
生成packag.json文件
-
npm init
安装gulp
-
npm install gulp -g 全局
-
npm install gulp --save-dev 本地
创建gulp任务:gulpfile.js
var gulp = require("gulp")
gulp.task("greet",function(){
console.log('hello world');
});
创建处理css文件的任务:
npm install gulp-cssnano --save-dev
var gulp = require("gulp")
var cssnano = require("gulp-cassnano")
gulp.task("css",function(){
gulp.src('./css/*.css')
.pipe(cassnano())
.pipe(gulp.dest("./css/dist"))
})
Blog
admin.py
from django.contrib import admin
from .models import Banner, Category, Tag, Tui, Article, Link
#导入需要管理的数据库表
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
list_display = ('id', 'category', 'title', 'tui', 'user', 'views', 'created_time')
# 文章列表里显示想要显示的字段
list_per_page = 50
# 满50条数据就自动分页
ordering = ('-created_time',)
#后台数据列表排序方式
list_display_links = ('id', 'title')
# 设置哪些字段可以点击进入编辑界面
@admin.register(Banner)
class BannerAdmin(admin.ModelAdmin):
list_display = ('id', 'text_info', 'img', 'link_url', 'is_active')
@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
list_display = ('id', 'name', 'index')
@admin.register(Tag)
class TagAdmin(admin.ModelAdmin):
list_display = ('id', 'name')
@admin.register(Tui)
class TuiAdmin(admin.ModelAdmin):
list_display = ('id', 'name')
@admin.register(Link)
class LinkAdmin(admin.ModelAdmin):
list_display = ('id', 'name','linkurl')
models.py
from django.db import models
from django.contrib.auth.models import User
# 导入Django自带用户模块
# 文章分类
class Category(models.Model):
name = models.CharField('博客分类', max_length=100)
index = models.IntegerField(default=999, verbose_name='分类排序')
class Meta:
verbose_name = '博客分类'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
# 文章标签
class Tag(models.Model):
name = models.CharField('文章标签', max_length=100)
class Meta:
verbose_name = '文章标签'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
# 推荐位
class Tui(models.Model):
name = models.CharField('推荐位', max_length=100)
class Meta:
verbose_name = '推荐位'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
# 文章
class Article(models.Model):
title = models.CharField('标题', max_length=70)
excerpt = models.TextField('摘要', max_length=200, blank=True)
category = models.ForeignKey(Category, on_delete=models.DO_NOTHING, verbose_name='分类', blank=True, null=True)
# 使用外键关联分类表与分类是一对多关系
tags = models.ManyToManyField(Tag, verbose_name='标签', blank=True)
# 使用外键关联标签表与标签是多对多关系
img = models.ImageField(upload_to='article_img/%Y/%m/%d/', verbose_name='文章图片', blank=True, null=True)
body = models.TextField()
user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='作者')
# """
# 文章作者,这里User是从django.contrib.auth.models导入的。
# 这里我们通过 ForeignKey 把文章和 User 关联了起来。
# """
views = models.PositiveIntegerField('阅读量', default=0)
tui = models.ForeignKey(Tui, on_delete=models.DO_NOTHING, verbose_name='推荐位', blank=True, null=True)
created_time = models.DateTimeField('发布时间', auto_now_add=True)
modified_time = models.DateTimeField('修改时间', auto_now=True)
class Meta:
verbose_name = '文章'
verbose_name_plural = '文章'
def __str__(self):
return self.title
# Banner
class Banner(models.Model):
text_info = models.CharField('标题', max_length=50, default='')
img = models.ImageField('轮播图', upload_to='banner/')
link_url = models.URLField('图片链接', max_length=100)
is_active = models.BooleanField('是否是active', default=False)
def __str__(self):
return self.text_info
class Meta:
verbose_name = '轮播图'
verbose_name_plural = '轮播图'
# 友情链接
class Link(models.Model):
name = models.CharField('链接名称', max_length=20)
linkurl = models.URLField('网址', max_length=100)
def __str__(self):
return self.name
class Meta:
verbose_name = '友情链接'
verbose_name_plural = '友情链接'
再次笔记
path(正则表达式, views视图函数,参数,别名),
前2个必须要写
每个url都带一个最前面的/ 所以不需要写
#(写也可以,如path('/admin/', admin.site.urls) 对应网址http://127.0.0.1:8000//admin/
说不定可起到保护作用哦!
在Python正则表达式中,命名正则表达式组的语法
(?P<name>pattern),其中name是组的名称
posted on 2019-08-20 14:24 、Discipline 阅读(227) 评论(0) 收藏 举报
浙公网安备 33010602011771号