一次只打开一次服务css
html
web服务器:负责处理http请求,响应静态文件,常见的有 Apache , Nginx前端
M :表明模型(Model),即数据存取层。 该层处理与数据相关的全部事务: 如何存取、如何验证有效node
T :表明模板(Template),即表现层。 该层处理与表现相关的决定: 如何在页面或其余类型文档中进行显示。python
V :表明视图(View),即业务逻辑层该层包含存取模型及调取恰当模板的相关逻辑。 你能够把它看做模型与模板之间的桥梁。mysql
经过URL对应关系匹配 ->找到对应的函数(或者类)->返回字符串(或者读取Html以后返回渲染的字符串)git
进入到虚拟环境 workon django-env github
想要在其余电脑上也能访问本网站,那么须要指定 ip 地址为 0.0.0.0web
建立应用(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>
{{ 'valude dsa'|cut:" " }} #删除空格
# 数据 context = { "birthday": datetime.now() } \# 模版 {{ birthday|date:"Y/m/d" }}
static中新建一个文件夹与父文件夹名字保持一致
{% load static %} <link rel="stylesheet" href="{% static 'style.css' %}">
TEMPLATES/OPTIONS #添加 52 'builtins': ['django.templatetags.static'] #之后在模版中就能够直接使用 static 标签
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', } }
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
一个表一个模型 表当中有多少个字段在模型中就有多少个属性
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中
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参数
直接输入,不须要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:压缩
https://github.com/coreybutler/nvm-windows/releases nvm-setup.zip
nvm install node 最新
nvm install version 指定
nvm use version 使用
nvm list 列出
nvm uninstall version 卸载
npm init
npm install gulp -g 全局
npm install gulp --save-dev 本地
var gulp = require("gulp") gulp.task("greet",function(){ console.log('hello world'); });
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")) })
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/
说不定可起到保护做用哦!
(?P<name>pattern),其中name是组的名称