[django]阅读笔记

https://dwz.cn/FUcnVGi8
1312420-20181110084256996-1537841205.png

新建目录

django-admin.exe startproject myblog

django-admin.exe startproject myblog .

1312420-20180830163133941-2046828071.png

django-admin命令

1312420-20180830162930367-1338670280.png

命令路径
1312420-20180830163338469-923401125.png

1312420-20180830163330633-1096771578.png

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

他们startapp功能相同
1312420-20180830162613497-269788330.png

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

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

app目录

1312420-20180830164253669-571573333.png

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的字段

1312420-20180830165228659-1902755386.png

1312420-20180831233355099-875142872.png

1312420-20180831233404155-214931743.png

1312420-20180831233411752-1736593105.png
1312420-20180831233419700-1913085511.png

1312420-20180831233427676-1476625961.png

1312420-20180831233433043-249933486.png

http的app

1312420-20180831233756840-1917514319.png

contrib
1312420-20180831234013431-1204347054.png

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

1312420-20180830170828353-597943496.png
生成了里面的内容, 是一些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时间,可以矫正下.
1312420-20180830172206833-609959368.png

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)

可以点进去看看有哪些选项
1312420-20180830173913678-1790929559.png

1312420-20180830173808409-2010438627.png
1312420-20180830173815185-1337847589.png

ORM

1312420-20180830174224240-1829186940.png
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: 条件

1312420-20180830182912568-582164715.png

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

1312420-20180830183334352-2145538959.png

注: 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')

1312420-20180831234138596-1006465478.png

# 扩展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',
]

1312420-20180901110433657-1446670660.png

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.csdn.net/Mr_JJ_Lian/article/details/6787786

django部署 gu or uwsgi

1312420-20180902200355924-31070372.png

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: 库--->生成模型

1312420-20180910214924642-17370812.png

orm使用原生的sql

https://docs.djangoproject.com/en/2.1/topics/db/sql/
https://my.oschina.net/watcher/blog/1573503
1312420-20180911110120474-135026557.png

1312420-20180911110318660-534937518.png

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

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

获取用户权限

1312420-20180911170926512-1865393041.png

request.GET request.POST属性和方法

  • request.get获取的是字典

http://127.0.0.1:8000/blog/?a=1
1312420-20180911194539207-150067279.png

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里是看不到这个字段的
1312420-20181026110057075-1241625961.png

还有类似的DateTimeField: django:DateTimeField如何自动设置为当前时间并且能被修改
http://www.nanerbang.com/article/5488/

djanog的QueryDict

1312420-20181028103508185-289730340.png

APPEND_SLASH = False

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

APPEND_SLASH = False

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

model自定义字段

1312420-20181104102150258-1091724782.png

css/js等静态文件找不到

但是我这个已经配置了

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

1312420-20181106161536095-591769457.png

原来是
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;',
        },
    }
}

转载于:https://www.cnblogs.com/iiiiiher/p/9560956.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值