[django]阅读笔记

时间:2023-03-09 18:04:56
[django]阅读笔记

https://dwz.cn/FUcnVGi8

[django]阅读笔记

新建目录

django-admin.exe startproject myblog

django-admin.exe startproject myblog .

[django]阅读笔记

django-admin命令

[django]阅读笔记

命令路径

[django]阅读笔记

[django]阅读笔记

manage.py是对django-admin命令的一个简答的封装

他们startapp功能相同

[django]阅读笔记

django-admin存在于安装django后/usr/local/bin/django-admin

manage.py创建目录后存在于当前目录

app目录

[django]阅读笔记

settings.py相关

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True # 为true时, allowhost可以为空, 生产为false+allow自己的域名 ALLOWED_HOSTS = [] # Internationalization
# https://docs.djangoproject.com/en/2.0/topics/i18n/ # i18n internationalization LANGUAGE_CODE = 'zh-hans' TIME_ZONE = 'Asia/Shanghai'

django源码目录(把django当作一个project)

如果你记不住settings.py里的字段名字 ,那请到global_settings.py里去查吧, 这里包含了所有settings.py的字段

[django]阅读笔记

[django]阅读笔记

[django]阅读笔记

[django]阅读笔记

[django]阅读笔记

[django]阅读笔记

[django]阅读笔记

http的app

[django]阅读笔记

contrib

[django]阅读笔记

from django.db import models

from django.contrib import admin
from django.urls import path from django.shortcuts import render from django.contrib import admin

makemigration

[django]阅读笔记

生成了里面的内容, 是一些py的类,

当model.py发生变化时候, 执行该命令, 会重新生成0002的文件.以此类推.

本质上是sql. 如何查看真实sql呢?

sqlmigrate blog 0001

CREATE TABLE "blog_blogarticle" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "title" varchar(300) NOT NULL, "body" text NOT NULL, "publish" datetime NOT NULL, "author_id" integer NOT NULL REFERENCES "auth_user" ("id") DEFERRABLE INITIALLY DEFERRED);
CREATE INDEX "blog_blogarticle_author_id_44cfb7b2" ON "blog_blogarticle" ("author_id");
COMMIT;
migrate  # 真正的执行sql.

settings.py控制插入数据库时时间

from django.contrib.auth.models import User
from django.db import models # Create your models here.
from django.utils import timezone class BlogArticles(models.Model):
title = models.CharField(max_length=300)
body = models.TextField()
publish = models.DateTimeField(default=timezone.now) ##################
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='blog_posts') class Meta:
ordering = ("-publish",) def __str__(self):
return self.title

默认是utc时间,可以矫正下.

[django]阅读笔记

LANGUAGE_CODE = 'zh-hans'

TIME_ZONE = 'Asia/Shanghai'

USE_TZ = False

admin后台选项

class BlogArticlesAdmin(admin.ModelAdmin):
list_display = ('title', 'author', 'publish')
list_filter = ('author', 'publish','title')
search_fields = ('title', 'body')
raw_id_fields = ('author',)
date_hierarchy = "publish"
ordering = ['author', 'publish'] admin.site.register(BlogArticles, BlogArticlesAdmin)

可以点进去看看有哪些选项

[django]阅读笔记

[django]阅读笔记

[django]阅读笔记

ORM

[django]阅读笔记

ORM的作用是在关系型数据库和业务实体对象之间进行映射,这样在操作业务对象时,就不需要再去和复杂的SQL语句打交道,只需简单地操作对象的属性和方法。

三大好处

可移植性强
安全性好,不需要考虑sql注入
查询简单

获取详情页

遵循规则:

首页: http://127.0.0.1:8000/blog/
详情: http://127.0.0.1:8000/blog/5/

django2的带参数url

path('<int:question_id>/', views.blog_article, name='blog_article'),

get_object_or_404

def blog_article(request, question_id):
# article = BlogArticles.objects.get(id=question_id)
article=get_object_or_404(BlogArticles, id=question_id) return render(request, 'blog/content.html', {'article': article}) get_object_or_404: 如果有返回实例, 如果无报404
get_object_ or_ 404(klass,*args, **kwargs)
kclass: 一个模型
args: 条件

[django]阅读笔记

template设置(django自动搜索模板规则)

[django]阅读笔记

注: template和static都是先在指定的目录下搜索, 然后在个app下搜索

maotaipro
├── tutorial
│ ├── __init__.py
│ ├── admin.py
│ ├── models.py
│ ├── templates
│ │ └── tutorial
│ │ ├── index.html
│ │ └── search.html
│ ├── tests.py
│ └── views.py
├── tryit
│ ├── __init__.py
│ ├── admin.py
│ ├── models.py
│ ├── templates
│ │ └── tryit
│ │ ├── index.html
│ │ └── poll.html
│ ├── tests.py
│ └── views.py
├── manage.py
└── maotaipro
├── __init__.py
├── settings.py
├── urls.py
└── wsgi.py

django template的查找机制

Django 模板查找机制: Django 查找模板的过程是在每个 app 的 templates 文件夹中找(而不只是当前 app 中的代码只在当前的 app 的 templates 文件夹中找)。各个 app 的 templates 形成一个文件夹列表,Django 遍历这个列表,一个个文件夹进行查找,当在某一个文件夹找到的时候就停止,所有的都遍历完了还找不到指定的模板的时候就是 Template Not Found (过程类似于Python找包)。这样设计有利当然也有弊,有利是的地方是一个app可以用另一个app的模板文件,弊是有可能会找错了。所以我们使用的时候在 templates 中建立一个 app 同名的文件夹,这样就好了。

static和collectstatic作用

STATIC_URL = '/static/'

# 当运行 python manage.py collectstatic 的时候
# STATIC_ROOT 文件夹 是用来将所有STATICFILES_DIRS中所有文件夹中的文件,以及各app中static中的文件都复制过来
# 把这些文件放到一起是为了用apache等部署的时候更方便
STATIC_ROOT = os.path.join(BASE_DIR, 'collected_static') 现在我们一般将静态文件放在指定的static下即可.
dj18static
├── blog
│ ├── __init__.py
│ ├── admin.py
│ ├── migrations
│ │ └── __init__.py
│ ├── models.py
│ ├── static # 应用 blog 下的 static, 默认会找这个文件夹
│ │ └── 【zqxt.png】
│ ├── tests.py
│ │
│ └── views.py
├── common_static # 已经添加到了 STATICFILES_DIRS 的文件夹
│ └── js
│ └── 【jquery.js】

├── dj18static
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── manage.py
# 这个是默认设置,Django 默认会在 STATICFILES_DIRS中的文件夹 和 各app下的static文件夹中找文件
# 注意有先后顺序,找到了就不再继续找了
STATICFILES_FINDERS = (
"django.contrib.staticfiles.finders.FileSystemFinder",
"django.contrib.staticfiles.finders.AppDirectoriesFinder"
)

form

from django import forms

class LoginForm(forms.Form):
username = forms.CharField()
password = forms.CharField(widget=forms.PasswordInput)
dir(LoginForm()), 发现有很多的属性,常用的如下

d = {'username':'maotai','password':'123'}
'is_bound', ******, 判断实例化时有没有传参数
'as_p', ******
'cleaned', ******
'clean_data', ****** 取出d = {'username':'maotai','password':'123'}
'is_valid', ****** 判断传参是否正确
'error_class', ****** 错误class
d = {'password': '123', 'username': 'maotai'}
lf = LoginForm(d) print(lf)
<tr><th><label for="id_username">Username:</label></th><td><input type="text" name="username" value="maotai" required id="id_username" /></td></tr>
<tr><th><label for="id_password">Password:</label></th><td><input type="password" name="password" required id="id_password" /></td></tr> lf.as_p()
Out[25]:
'<p><label for="id_username">Username:</label> <input type="text" name="username" value="maotai" required id="id_username" /></p>\n<p><label for="id_password">Password:</label> <input type="password" name="password" required id="id_password" /></p>' lf.is_bound
Out[18]:
True lf.is_valid()
Out[19]:
True lf.cleaned_data
Out[22]:
{'password': '123', 'username': 'maotai'} lf.errors
Out[12]:
{'username': ['这个字段是必填项。']}

自定义认证界面, django的authenticate, login

前端输入的登录表单ok ---> auth用户名密码 --> 执行login分配sessionid登录完成

from django.contrib.auth import authenticate, login
from django.http import HttpResponse
from django.shortcuts import render from account.forms import LoginForm def user_login(request):
if request.method == "POST":
print(request.POST)
login_form = LoginForm(request.POST)
if login_form.is_valid():
cd = login_form.cleaned_data
print(cd)
user = authenticate(username=cd['username'], password=cd['password'])
if user:
login(request, user)
return HttpResponse('login succ')
else:
return HttpResponse('error')
return render(request, 'account/login.html')

[django]阅读笔记

# 扩展django默认的user表
AUTH_USER_MODEL = "users.UserProfile" # 自定义认证逻辑backend
AUTHENTICATION_BACKENDS = ('users.views.CustomBackend',) 默认: AUTHENTICATION_BACKENDS = ['django.contrib.auth.backends.ModelBackend']

https://www.cnblogs.com/iiiiiher/p/8331268.html

https://www.cnblogs.com/iiiiiher/p/8395177.html

from django.contrib.auth import authenticate, login
from django.contrib.auth.backends import ModelBackend
from django.shortcuts import render # Create your views here.
from users.models import UserProfile # 自定义authenticate backend的处理认证逻辑
## 密码对返回user 密码错返回none
class CustomBackend(ModelBackend): # 继承认证类,diy它
def authenticate(self, request, username=None, password=None, **kwargs):
try: # 验证用户名密码 否则返回None
user = UserProfile.objects.get(username=username) # 表示有这个用户 查处自定义usermodel的用户名,
from django.db.models import Q #或的关系
user = UserProfile.objects.get(Q(username=username) | Q(email=username))
if user.check_password(password): # 表示这个用户密码正确, 这里django存储密码是加密的,必须用其下这个方法加密后比对是否正确
return user
except Exception as e:
return None # 密码错误返回None # 获取用户名密码-->表单验证-->authenticate backend的处理认证逻辑-->login登录 def user_login(request):
if request.method == "POST":
user_name = request.POST.get("username", "")
pass_word = request.POST.get("password", "")
user = authenticate(username=user_name, password=pass_word)
if user is not None: # 用户名密码验证成功
login(request, user) # django执行用户登录
return render(request, "index.html")
else:
return render(request, "index.html", {}) elif request.method == "GET":
return render(request, "login.html", {})

django的标准库contrib

http://djangobook.py3k.cn/2.0/chapter16/

Django标准库
Django的标准库存放在 django.contrib 包中。每个子包都是一个独立的附加功能包。 这些子包一般是互相独立的,不过有些django.contrib子包需要依赖其他子包。 在 django.contrib 中对函数的类型并没有强制要求 。其中一些包中带有模型(因此需要你在数据库中安装对应的数据表),但其它一些由独立的中间件及模板标签组成。 django.contrib 开发包共有的特性是: 就算你将整个django.contrib开发包删除,你依然可以使用 Django 的基础功能而不会遇到任何问题。 当 Django 开发者向框架增加新功能的时,他们会严格根据这一原则来决定是否把新功能放入django.contrib中。 django.contrib 由以下开发包组成: admin : 自动化的站点管理工具。 请查看第6章。 admindocs:为Django admin站点提供自动文档。 本书没有介绍这方面的知识;详情请参阅Django官方文档。 auth : Django的用户验证框架。 参见第十四章。 comments : 一个评论应用,目前,这个应用正在紧张的开发中,因此在本书出版的时候还不能给出一个完整的说明,关于这个应用的更多信息请参见Django的官方网站. 本书没有介绍这方面的知识;详情请参阅Django官方文档。 contenttypes : 这是一个用于引入文档类型的框架,每个安装的Django模块作为一种独立的文档类型。 这个框架主要在Django内部被其他应用使用,它主要面向Django的高级开发者。 可以通过阅读源码来了解关于这个框架的更多信息,源码的位置在 django/contrib/contenttypes/。 csrf : 这个模块用来防御跨站请求伪造(CSRF)。参 见后面标题为”CSRF 防御”的小节。 databrowse:帮助你浏览数据的Django应用。 本书没有介绍这方面的知识;详情请参阅Django官方文档。 flatpages : 一个在数据库中管理单一HTML内容的模块。 参见后面标题为“Flatpages”的小节。 formtools:一些列处理表单通用模式的高级库。 本书没有介绍这方面的知识;详情请参阅Django官方文档。 gis:为Django提供GIS(Geographic Information Systems)支持的扩展。 举个例子,它允许你的Django模型保存地理学数据并执行地理学查询。 这个库比较复杂,本书不详细介绍。 请参看http://geodjango.org/上的文档。 humanize : 一系列 Django 模块过滤器,用于增加数据的人性化。 参阅稍后的章节《人性化数据》。 localflavor:针对不同国家和文化的混杂代码段。 例如,它包含了验证美国的邮编 以及爱尔兰的身份证号的方法。 markup : 一系列的 Django 模板过滤器,用于实现一些常用标记语言。 参阅后续章节《标记过滤器》。 redirects : 用来管理重定向的框架。 参看后面的“重定向”小节。 sessions : Django 的会话框架。 参见14章。 sitemaps : 用来生成网站地图的 XML 文件的框架。 参见13章。 sites : 一个让你可以在同一个数据库与 Django 安装中管理多个网站的框架。 参见下一节: syndication : 一个用 RSS 和 Atom 来生成聚合订阅源的的框架。 参见13章。 webdesign:对设计者非常有用的Django扩展。 到编写此文时,它只包含一个模板标签{% lorem %}。详情参阅Django文档。

shortcut快捷函数

This module collects helper functions and classes that "span" multiple levels
of MVC. In other words, these functions/classes introduce controlled coupling
for convenience's sake.
django.shortcuts 收集了“跨越” 多层MVC 的辅助函数和类。 换句话讲,这些函数/类为了方便,引入了可控的耦合。

django中间件, 从请求到view

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',
]

[django]阅读笔记

django 中的render和render_to_response()和locals()

http://www.cnblogs.com/wangchaowei/p/6750512.html

return render(request, 'blog_add.html', {'blog': blog, 'form': form, 'id': id, 'tag': tag})
 return render_to_response('blog_add.html', {'blog': blog, 'form': form, 'id': id, 'tag': tag})

很明显,如果使用render_to_response就省去了render里传递的request。

1.加载template

2.生成contenxt

3.render成字符串

4.httpresponse返回

使用render_to_response的背景

由于加载模板、填充 context 、将经解析的模板结果返回为 HttpResponse 对象这一系列操

作实在太常用了,Django 提供了一条仅用一行代码就完成所有这些工作的捷径。

该捷径就是位于 django.shortcuts 模块中名为 render_to_response() 的函数。

大多数时候,你将使用 render_to_response() ,而不是手动加载模板、创建 Context 和 HttpResponse 对象。

实例

下面就是使用 render_to_response() 重新编写过的 current_datetime 范例。

from django.shortcuts import render_to_response
import datetime
def current_datetime(request):
now = datetime.datetime.now()
return render_to_response('current_datetime.html', {'current_date': now})

render_to_response总结

大变样了!让我们逐句看看代码发生的变化:

1.我们不再需要导入 get_template 、 Template 、 Context 和 HttpResponse 。

2.相反, 我们导入 django.shortcuts.render_to_response 。

3.import datetime 继续保留.

4.在 current_datetime 函数中,我们仍然进行 now 计算,但模板加载、上下文创建、模板解析和 HttpResponse 创建工作均在对 render_to_response() 的调用中完成了。

5.由于 render_to_response() 返回 HttpResponse 对象,因此我们仅需在视图中return 该值。

6.render_to_response() 的第一个参数必须是要使用的模板名称。

7.如果要给定第二个参数,那么该参数必须是为该模板创建 Context 时所使用的字典。如果不提供第二个参数,render_to_response() 使用一个空字典。

https://blog.****.net/Mr_JJ_Lian/article/details/6787786

django部署 gu or uwsgi

[django]阅读笔记

django的models.DateTimeField

- 有字段可以填写
from django.utils import timezone class BlogArticles(models.Model):
title = models.CharField(max_length=300)
body = models.TextField()
publish = models.DateTimeField(default=timezone.now)
auto_now=true          # 前端无法显示字段, 创建时间
auto_now_add=true # 更新时间

子表获取父表的数据

方法1:
class BlogArticles(models.Model):
title = models.CharField(max_length=300)
body = models.TextField()
publish = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='blog_posts') 前端:
<small>{{ article.author.username }}</small>

参考: https://www.cnblogs.com/iiiiiher/p/9560240.html

inspectdb: 库--->生成模型

[django]阅读笔记

orm使用原生的sql

https://docs.djangoproject.com/en/2.1/topics/db/sql/

https://my.oschina.net/watcher/blog/1573503

[django]阅读笔记

[django]阅读笔记

debug =false不仅影响static 还能让allow_host失效

==true会使得不去查app/static/app/xxx.css

获取用户权限

[django]阅读笔记

request.GET request.POST属性和方法

  • request.get获取的是字典

http://127.0.0.1:8000/blog/?a=1

[django]阅读笔记

uuid和datetime

http://blog.51cto.com/xujpxm/2090382

class Datacenter(models.Model):
id = models.UUIDField('机房ID', default=uuid.uuid4, primary_key=True)
zone = models.ForeignKey(Zone, verbose_name='所在区域', on_delete=models.PROTECT)
dc_name = models.CharField('机房', max_length=128, unique=True)
networks = models.CharField('IP地址段', max_length=128, blank=True, unique=True)
update_time = models.DateTimeField('更新时间', auto_now=True) def __str__(self):
return self.dc_name class Meta:
verbose_name = '机房配置'
verbose_name_plural = '机房配置'
from datetime import datetime
add_time = models.DateTimeField(default=datetime.now) publish = models.DateTimeField(default=timezone.now) auto_now=true # 前端无法显示字段, 创建时间
auto_now_add=true # 更新时间

默认主键用的是AutoField,作为pk,每次自增1

class Blog(models.Model):
sid = models.AutoField(primary_key=True)

admin里是看不到这个字段的

[django]阅读笔记

还有类似的DateTimeField: django:DateTimeField如何自动设置为当前时间并且能被修改

http://www.nanerbang.com/article/5488/

djanog的QueryDict

[django]阅读笔记

APPEND_SLASH = False

https://www.liurongxing.com/django-append_slash-true.html

APPEND_SLASH = False

http://example.com/hello
自动跳转到
http://example.com/hello/

model自定义字段

[django]阅读笔记

css/js等静态文件找不到

但是我这个已经配置了

STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static', ),
)

[django]阅读笔记

原来是

debug=false了. 靠.

连接mysql

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'bbs',
'USER': 'root',
'PASSWORD': '123456',
'HOST': '127.0.0.1',
'PORT': 3306,
'OPTIONS':{
'init_command': 'SET default_storage_engine=INNODB;',
},
}
}