安装:pip install django==2.0.4 (不指定版本默认安装最新版本)
创建django项目:
- 创建一个文件夹,进入里面在url输入cmd进入命令行模式
- 输入django-admin startproject amberserver此时django的目录结构就已创建
- python manage.py runserver启动server,打开127.0.0.1就可以访问
urls.py解析
from django.contrib import admin
from django.urls import path
urlpatterns = [
path('admin/', admin.site.urls),
]
path的作用:是规定某些url有效,与re_path的区别是re代表用正则的格式来完成第一个参数
path传递参数:path('news/int:<id>', news_detail, name='news_detail'),id必须与news_detail方法的参数id一致
在创建项目amberserver时生成的url下:path('new/', include("news.urls")) 通过new/直接到news里url继续拼接url(此处有点,amberserver和news是两个同级目录不需要引用直接就写路径名)
初始化数据库:python manage.py migrate 会在manage.py同级目录生成db.sqlite3文件
创建超级管理员:python manage.py createsuperuser设置用户名和密码
打开浏览器输入:127.0.0.1:8000/admin 输入上一步的用户名和密码即可登录
创建django app:python manage.py startapp 【news】会在manage.py同级目录生成news文件,包含module.py,若想使其生效要在settings.py文件里的INSTALLED_APPS把news加上
module.py解析
from django.db import models
# Create your models here.
class Blog(models.Model):
title = models.CharField(max_length=50)
content = models.TextField()
blog_type = models.ForeignKey(BlogType, on_delete=models.DO_NOTHING)
author = models.ForeignKey(User, on_delete=models.DO_NOTHING)
created_on = models.DateTimeField(auto_now_add=True)
updated_on = models.DateTimeField(auto_now=True)
# 这里的外键BlogType是整个对象
除了上述的内容数据库会默认加上id这个参数,表名默认是所属文件夹名+类名合成
时间参数auto_now_add代表创建时自动加上当前时间,auto_now代表自动更新该项内容
__str__代表查询出的对象显示的样式
PS:若数据库已经有数据但仍想插入新列,推荐使用default参数指定
查找数据库数据:
from django.shortctus import get_object_or_404
get():data = Article.Objects.get(title="abc")参数可以用默认的pk=2 , 若存在返回Article对象,Article.title可直接获取value,查找不到报错,建议使用try抓住异常
data = Article.Objects.all() 查找Article表的所有数据,QuerySet类型,遍历后得到对象
data = Article.Objects.all().count() 获取数量
data = get_object_or_404(Article, title="abc") 不需要抓取异常
安装包使用:
pip freeze > requirements.txt 将要安装的包保存到指定文件
pip install -r requirements.txt
插入数据
>>> from django.contrib.auth.models import User
>>> user = User.objects.all()[0]
>>> for i in range(1, 30):
... blog = Blog()
... blog.blog_type =blog_type
... blog.title = "number %s" % i
... blog.content = "xxx %s" % i
... blog.author = user
... blog.save()
# 注意这里的author是外键,传入的是对象不是字符串
分页器实现分页
>>> from django.core.paginator import Paginator
>>> from blog.models import Blog
>>> blogs = Blog.objects.all()
>>> paginator = Paginator(blogs, 10)
>>> dir(paginator)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_check_object_list_is_ordered', '_get_page', 'allow_empty_first_page', 'count', 'get_page', 'num_pages', 'object_list', 'orphans', 'page', 'page_range', 'per_page', 'validate_number']
>>> a=paginator.get_page(2)
>>> a
<Page 2 of 4>
>>> dir(a)
['__abstractmethods__', '__class__', '__contains__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', '__weakref__', '_abc_impl', 'count', 'end_index', 'has_next', 'has_other_pages', 'has_previous', 'index', 'next_page_number', 'number', 'object_list', 'paginator', 'previous_page_number', 'start_index']
>>> a.object_list
<QuerySet [<Blog: number 19>, <Blog: number 18>, <Blog: number 17>, <Blog: number 16>, <Blog: number 15>, <Blog: number 14>, <Blog: number 13>, <Blog: number 12>, <Blog: number 11>, <Blog: number 10>]>
>>> a.number
2
这里把blogs传递给前端,blogs是获取指定页数的值
<div>
<ul class="pagination">
<li>
{% if blogs.has_previous %}
<a href="?page={{ blogs.previous_page_number }}" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
{% else %}
<span aria-hidden="true">«</span>
{% endif %}
</li>
{# page_range: 所有的页数 #}
{% for page_num in page_range %}
{% if page_num == blogs.number %}
<li class="active"><span>{{ page_num }}<span>
{% else %}
<li><a href="?page={{ page_num }}">{{ page_num }}</a></li>
{% endif %}
{% endfor %}
<li>
{% if blogs.has_next %}
<a href="?page={{ blogs.next_page_number }}" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
{% else %}
<span aria-hidden="true">»</span>
{% endif %}
</li>
</ul>
</div>
XXX.objects.filter(id__range=(3,7)) 反查询用XXX.objects.exclude(id__range=(3,7))
查询年份是2017年的数据:XXX.objects.filter(created_on__year=2017)
在数据库加参数传递
type_and_count = []
types = BlogType.objects.all()
for type in types:
blog_count = Blog.objects.filter(blog_type=type).count()
type.blog_count = blog_count
type_and_count.append(type)
# type.blog_count就是临时给type对象加blog_count这个属性
# 可以使用annotate方法代替,blog_count是临时加的变量名,Count方法统计个数
from django.db.models import Count
BlogType.objects.annotate(blog_count=Count('blog'))
内容字段连接富本编辑器
安装:pip install django-ckeditor
注册:在全局settings文件的INSTALLES_APPS里添加'ckeditor'
使用:在module.py模块里调用
from ckeditor.fields import RichTextField
class Blog(models.Model):
title = models.CharField(max_length=50)
content = RichTextField()
# 没有models
缺点:上述编辑器若想添加图片不支持本地上传,需要令安装其他插件
安装:pip install pillow
注册:在全局settings文件的INSTALLES_APPS里添加'ckeditor_uploader'
在全局urls.py里追加默认path:path('ckeditor', include('ckeditor_uploader.urls'))
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
from . import views
urlpatterns = [
path('', views.home, name="home"),
path('admin/', admin.site.urls),
path('blog/', include("blog.urls")),
path('ckeditor', include('ckeditor_uploader.urls')),
]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
# ckeditor是默认配置