Django笔记

Django笔记

一次只打开一次服务

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  阅读(210)  评论(0编辑  收藏  举报

导航