Django进阶学习
回顾上一章
改变模型需要这三步:
编辑 models.py 文件,改变模型。
运行 python manage.py makemigrations 为模型的改变生成迁移文件。
运行 python manage.py migrate 来应用数据库迁移。创建超级用户并添加 标题/内容/时间:
python manage.py createsuperuser
class ArticleAdmin(admin.ModelAdmin):
list_display = ('title', 'content', 'pub_time')
list_filter = ('pub_time',) #添加时间过滤器
admin.site.register(Article, ArticleAdmin)
- 注意path与url的区别:URL里是正则表达式,而path则要改成re_path才行
from django.urls import path, re_path
urlpatterns = [
path('index/', views.index),
re_path('article/(?P<article_id>[0-9]+)$', views.article_page, name='article_page'),
re_path('edit/(?P<article_id>[0-9]+)$', views.edit_page, name='edit_page'),
path('edit/action/', views.edit_action, name='edit_action'),
]
模型
一般来说,每一个模型都映射一个数据库表。
# models.py
from django.db import models
class Article(models.Model):
title = models.CharField(max_length=32, default='Title')
content = models.TextField(null=True)
以上的类名代表了数据库表名,且继承了models.Model,类里面的字段代表数据表中的字段(name),数据类型则由CharField(相当于varchar)、DateField(相当于datetime), max_length 参数限定长度。
添加数据需要先创建对象,然后再执行 save 函数,相当于SQL中的INSERT:
article = models.Article.objects.get(pk=article_id) ## 获取单个对象
article.title = title
article.content = content
article.save()
return render(request, 'blog/article_page.html', {'article': article})
Django提供了多种方式来获取数据库的内容:
articles = models.Article.objects.all() # 通过objects这个模型管理器的all()获得所有数据行,相当于SQL中的SELECT * FROM
response2 = Test.objects.filter(id=1) # filter相当于SQL中的WHERE,可设置条件过滤结果
Test.objects.order_by("id") #数据排序
更新数据:
# 数据库操作
def testdb(request):
# 修改其中一个id=1的name字段,再save,相当于SQL中的UPDATE
test1 = Test.objects.get(id=1)
test1.name = 'Google'
test1.save()
return HttpResponse("<p>修改成功</p>")
删除数据:删除数据库中的对象只需调用该对象的delete()方法即可
# 数据库操作
def testdb(request):
# 删除id=1的数据
test1 = Test.objects.get(id=1)
test1.delete()
return HttpResponse("<p>删除成功</p>")
Django 表单
HTTP请求
HTTP协议以”请求-回复”的方式工作。客户发送请求时,可以在请求中附加数据。服务器通过解析请求,就可以获得客户传来的数据,并根据URL来提供特定的服务。
在blog应用中:
def edit_action(request):
title = request.POST.get('title', 'title')
content = request.POST.get('content', 'CONTENT')
article_id = request.POST.get('article_id', '0')
if article_id == '0':
models.Article.objects.create(title=title, content=content)
articles = models.Article.objects.all()
return render(request, 'blog/index.html', {'articles': articles})
article = models.Article.objects.get(pk=article_id)
article.title = title
article.content = content
article.save()
return render(request, 'blog/article_page.html', {'article': article})
用函数edit_action处理响应,当用户点击的是新文章时,则得到的id是0,保存好文章后返回的是首页; 当用户点击的修改文章时,修改完保存后返回的是文章页面。
Request 对象
每个 view 函数的第一个参数是一个 HttpRequest 对象,就像下面这个 index() 函数:
def index(request):
return HttpResponse('Hello world')
Django Admin 管理工具
搜索功能在管理大量记录时非常有,我们可以使用 search_fields 为该列表页增加搜索栏:
class ArticleAdmin(admin.ModelAdmin):
list_display = ('title', 'content', 'pub_time')
list_filter = ('pub_time',)
search_fields = ('title',)
其中 list_display 属性是为了在列表中显示更多的栏目
Django 数据导入
新建一个项目 mysite1, 再新建一个 app,名称为blog
- 输入 python manage.py shell
>>> from blog.models import Blog
>>> Blog.objects.create(title="The first blog of my site",
content="I am writing my blog on Terminal")
还有两种方法:
>>> blog2 = Blog()
>>> blog2.title = "title 2"
>>> blog2.content = "content 2"
>>> blog2.save()
或者
>>> blog2 = Blog(title="title 2",content="content 2")
>>> blog2.save()
- 批量导入
比如导入一个文本,里面是标题和内容,中间用四个*隔开的,示例(oldblog.txt)。在 最外面那个 mysite目录下写一个脚本,叫 txt2db.py,把 oldblog.txt 也放在mysite下,txt2db.py的代码为:
#!/usr/bin/env python
# coding:utf-8
import os, django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite1.settings")
django.setup()
from blog.models import Blog
def main():
f = open('oldblog.txt')
for line in f:
title, content = line.split('****')
Blog.objects.create(title=title, content=content)
f.close()
if __name__ == "__main__":
main()
print('Done!')
在终端运行python txt2db.py
则导入成功。
导入重复时解决办法
只要把上面的Blog.objects.create(title=title,content=content)
改成Blog.objects.get_or_create(title=title,content=content)
Model.objects.bulk_create() 更快更方便。将以上代码改成:
#!/usr/bin/env python
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
def main():
from blog.models import Blog
f = open('oldblog.txt')
BlogList = []
for line in f:
title,content = line.split('****')
blog = Blog(title=title,content=content)
BlogList.append(blog)
f.close()
Blog.objects.bulk_create(BlogList)
if __name__ == "__main__":
main()
print('Done!')
由于Blog.objects.create()每保存一条就执行一次SQL,而bulk_create()是执行一条SQL存入多条数据,做会快很多
Django 数据迁移
简单的迁移
django中导出的方法 python manage.py dumpdata, 不指定 appname 时默认为导出所有的app。也可以指定其中一个app,例如导出app中的blog:python manage.py dumpdata blog。
django中数据导入的方法:python manage.py loaddata blog_dump.json。不需要指定 appname用 Django 自带的命令
从原来的整个数据库导出所有数据
python manage.py dumpdata > mysite_all_data.json
将mysite_all_data.json传送到另一个服务器或电脑上导入
python manage.py loaddata mysite_all_data.json