文章目录
Django开发笔记
概述
注:笔者所用的环境版本为:Python 3.7 + Django 1.11
Django框架的优点
- 自带强大的后台功能
- 自带ORM
- 错误提示详细
- 优雅的网址
- 强大的数据库功能
模板
模板是一种文本,用于分离表现形式和内容
Django模板的使用方法
- 用原始的模板代码字符串创建一个Template对象
- 调用模板对象的render方法,并且闯入一套变量context
同步MySQL数据库 https://www.cnblogs.com/zhangxinqi/p/9094953.html#_label2
URL命名组
urlpatterns += patterns('lesson.views',
(r'^book/(?P<year>\d+)(?P<month>\d+)/$', hello),
)
#调用:
hello(request, year=2012, month=10)
django模板继承 (extend)
摘录自:https://www.cnblogs.com/yxwang/p/7847191.html
Django模版引擎中最强大也是最复杂的部分就是模版继承了。模版继承可以让您创建一个基本的“骨架”模版,它包含您站点中的全部元素,并且可以定义能够被子模版覆盖的 blocks 。
base:
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="style.css" />
<title>{% block title %}My amazing site{%/span> endblock %}</title>
</head>
<body>
<div id="sidebar">
{% block sidebar %}
<ul>
<li><a href="/">Home</a></li>
<li><a href="/blog/">Blog</a></li>
</ul>
{% endblock %}
</div>
<div id="content">
{% block content %}{% endblock %}
</div>
</body>
</html>
子模板:
{% extends "base.html" %}
{% block title %}My amazing blog{% endblock %}
{% block content %}
{% for entry in blog_entries %}
<h2>{{ entry.title }}</h2>
<p>{{ entry.body }}</p>
{% endfor %}
{% endblock %}
注意:
- 如果你在模版中使用 {% extends %} 标签,它必须是模版中的第一个标签。其他的任何情况下,模版继承都将无法工作。
- 在base模版中设置越多的 {% block %} 标签越好。请记住,子模版不必定义全部父模版中的blocks,所以,你可以在大多数blocks中填充合理的默认内容,然后,只定义你需要的那一个。多一点钩子总比少一点好。
- 如果你发现你自己在大量的模版中复制内容,那可能意味着你应该把内容移动到父模版中的一个 {% block %} 中。
include()
作用:Including other URLconfs
from django.conf.urls import include, url
urlpatterns = [
# ... snip ...
url(r'^community/', include('django_website.aggregator.urls')),
url(r'^contact/', include('django_website.contact.urls')),
# ... snip ...
]
- 注意include之前的正则表达式没有终止符 $ 而是 /
- 当调用clude时,把url前边正则表达式匹配到的chop off(砍掉),剩下的string传递到include的urls中进行进一步操作。
修改(重写)原生模板(admin, registration等中的模板)
参考:https://blog.csdn.net/robinliu2010/article/details/7649190
全局覆盖模板
admin视图使用标准模板载入机制来寻找模板,所以如果你在你的模板目录里创建模板 ,Django将载入并使用这些模板而不是使用Django绑定的默认admin模板 。
这些全局模板如下:
视图 基本模板名
更改列表 admin/change_list.html
增加/编辑表单 admin/change_form.html
删除确认 admin/delete_confirmation.html
对象历史 admin/object_history.html
尽管如此,大多数情况下你只想更改一个单独的对象或者app的模板而不是全局的模板
这样的话,每个admin视图首先寻找模型和app专有的模板,这些视图按下面的顺序寻找模板:
admin/<app_lable>/<object_name>/.html
admin/<app_lable>/.html
admin/.html
例如,在bookstore app的Book模型的增加/编辑表单的视图(第6章的例子)按下面的顺序寻找模板:
admin/bookstore/book/change_form.html
admin/bookstore/change_form.html
admin/change_form.html
修改原生模板的步骤
admin管理系统的模板路径默认为 python目录下的 /site-packages/django/contrib/admin/templates
static静态文件目录为 python目录下的 /site-packages/django/contrib/admin/static
- 在我们的项目根目录下建立一个子templates目录 。
- 复制site-packages/django/contrib/admin/templates目录下的文件到该目录下
- 修改setting.py文件中的配置项TEMPLATES, 将DIRS的值设置为[os.path.join(BASE_DIR, ‘templates’)]。
'DIRS': [os.path.join(BASE_DIR, 'templates')],
其中BASE_DIR为
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
- 此时,admin会先在当前项目目录下寻找模板,没有才会去python目录: /site-packages/django/contrib/admin/templates下找
定制模型模板
大多数情况下,你想使用上面第一个模板来创建模型专有的模板
通常情况下通过扩展基本模板并在其中的块定义中添加信息会将这个任务完成的最好
{% extends "admin/change_form.html" %}
{% block form_top %}
<p>Insert meaningful help message here..</p>
{% endblock %}
所有的这些模板都定义了一些块来让你覆盖,对于大多数程序,代码就是最好的文档,所以我们鼓励你浏览admin模板 (在django/contrib/admin/templates/里面)来得到最新的信息
定制JavaScript
定制admin视图
覆盖内建的视图
一些插件
MPTT
浅谈层级结构和Django中的mptt:https://blog.csdn.net/u013007900/article/details/78093563
django-mptt创建树结构并渲染:https://blog.csdn.net/u010042585/article/details/79892073
Modified Preorder Tree Traversal 一种数据库中存储层级数据(树形数据)的技术。
使大多数树操作在查询方面更高效。实际上,所有这些操作最多需要一个查询,有时为零
查询次数为零:
- 获取节点的后代
- 获取节点的祖先
- 在给定的级别上获取所有节点
- 获取叶子节点
这个不需要再次查询数据库:
- 计算给定节点的后代的数量
使用方法:
- pip3 install django-mptt
INSTALLED_APPS = (
# ...
'mptt',
)
- 创建评论模型,需要继承MPTTModel,并且有一个parent字段
#由于继承MPTTModel,评论模型就有了level,lft, rght和tree_id字段,这些字段是MPTT算法所使用的,一般不会用到
from mptt.fields import TreeForeignKey
from mptt.models import MPTTModel
class Comments(MPTTModel):
user = models.ForeignKey(User)
content = models.TextField()
parent = models.TreeForeignKey('self', null=True, blank=True, related_name='children',db_index=True)
post = models.ForeignKey(Post)
created_time = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.content
class MPTTMeta:
order_insertion_by = ['-created_time']
- 迁移数据库
python manage.py makemigrations
python manage.py migrate - 如果有自带的Admin,只需在admin.site注册,就可以在Admin模板中像这样显示数据:
#
from django.contrib import admin
from mptt.admin import MPTTModelAdmin
admin.site.register(MPTTFood, MPTTModelAdmin)
- 接下来,就是怎样在模板中显示的问题。
template:
{% load mptt_tags %}
{% recursetree nodes %}
<li>
{% if node.is_leaf_node %}
<span style="color: red;">{{ node.title }}</span>
{% else %}
{{ node.title }}
<ul>
{{ children }}
</ul>
{% endif %}
</li>
{% endrecursetree %}
views:
def mptt(request):
nodes = MPTTFood.tree.all()
return render_to_response('mpttexample/mptt.html', {'nodes': nodes})
mptt也可以用于类似权限管理等和树形有关的应用。
我们将Group做成一个mptt的树形结构,每一个Group有不同的权限。如果我们需要在数据库中手工维护这个树形结构,就会花费大量的时间,而mptt却已经帮你实现了。所以我们只需要用别的方式去实现Group的权限分配就好了。
class GroupProfile(MPTTModel):
name = models.CharField(max_length=50, unique=True)
user_group = models.OneToOneField(Group, null=True, blank=True, related_name='user_profile')
admin_group = models.OneToOneField(Group, null=True, blank=True, related_name='admin_profile')
superadmin = models.ForeignKey(User, null=True, related_name='group_profile')
parent = TreeForeignKey('self', null=True, blank=True, related_name='children', db_index=True)
class Meta:
permissions = (
('view_groupprofile', 'Can view Group Profile'),
)
django-sitetree实现导航栏
Github官网:https://github.com/idlesign/django-sitetree
参考:https://www.jianshu.com/p/8be1281f57e8
使用方法:
- 源码目录中有demo工程
- 修改项目配置:只需要在setting文件中的INSTALL_APPS项目中加入sitetree就可以使用
- 添加目录结构:在Django的admin中能看到SITE TRESS。可以进入sitetree编辑页面,根据需要编辑生成目录结构了
- 在HTML文件中引入目录结构:参考Demo工程中的listing_bootstrap3.html的文件,就可以展示出符合bootstrap3风格的目录效果
适配Metronic模版:见https://www.jianshu.com/p/8be1281f57e8
FlexSlider
参考:https://www.cnblogs.com/junhaoliu/p/6084281.html
Flexslider具有以下特性:
- 支持滑动和淡入淡出效果。
- 支持水平、垂直方向滑动。
- 支持键盘方向键控制。
- 支持触控滑动。
- 支持图文混排,支持各种html元素。
- 自适应屏幕尺寸。
- 可控制滑动单元个数。
- 更多选项设置和回调函数。
使用方法:
- 在head部分载入jquery库文件和Flexslider插件,以及Flexslider所需的基本css样式文件
<link href="//cdn.bootcss.com/flexslider/2.6.3/flexslider.min.css" rel="stylesheet">
<script src="//cdn.bootcss.com/jquery/2.2.2/jquery.min.js"></script>
<script src="//cdn.bootcss.com/flexslider/2.6.3/jquery.flexslider-min.js"></script>
- 然后在body中加入以下HTML代码:
<div class="flexslider">
<ul class="slides">
<li><img src="images/s1.jpg" /></li>
<li><img src="images/s2.jpg" /></li>
<li><img src="images/s3.jpg" /></li>
<li><img src="images/s4.jpg" /></li>
</ul>
</div>
使用了.flexslider来包括所有需要滚动的内容元素,然后使用<ul class="slides">
这个class非常关键,内部的滚动内容都是针对.slides的,然后在<li>
内部加入任意html元素,包括图片和文字。
jQuery
调用Flexslider插件非常简单,使用如下代码:
$(function() {
$(".flexslider").flexslider();
});
然后预览网页效果,一个内容切换效果就完成了,当然想要更多个性化设置,flexslider提供了丰富的选项配置以及回调函数绝对可以满足大多数开发者需求。
Flexslider选项设置:
$(window).load(function() {
$('.flexslider').flexslider({
animation: "fade", //图片变换方式:淡入淡出或者滑动
slideDirection: "horizontal", //图片设置为滑动式时的滑动方向:左右或者上下
slideshow: true, //载入页面时,是否自动播放
slideshowSpeed: 7000, //自动播放速度毫秒
animationDuration: 600, //内容切换时间
touch: //是否支持触摸滑动
directionNav: true, //是否显示左右控制按钮
controlNav: true, //是否显示控制菜单
keyboardNav: true, //键盘左右方向键控制图片滑动
mousewheel: false, //鼠标滚轮控制制图片滑动
minItems:1 //一次最少展示滑动内容的单元个数
maxItems:0 //一次最多展示滑动内容的单元个数
move:0 //一次滑动的单元个数
prevText: "Previous", //String: 上一项的文字
nextText: "Next", //String: 下一项的文字
pausePlay: false, //Boolean: 是否显示播放暂停按钮
pauseText: 'Pause', //String: 暂停文字
playText: 'Play', //String: 播放文字
randomize: false, //Boolean: 是否随机幻灯片
slideToStart: 0, //Integer: 初始化第一次显示图片位置
animationLoop: true, //是否循环滚动
pauseOnAction: true, //Boolean: Pause the slideshow when interacting with control elements, highly recommended.
pauseOnHover: false, //鼠标滑向滚动内容时,是否暂停滚动
pauseOnHover: false, //鼠标糊上去是否暂停
controlsContainer: "", //Selector: be taken.
manualControls: "", //自定义控制导航
manualControlEvent:"", //String:自定义导航控制触发事件:默认是click,可以设定hover
start: function(){}, //加载第一页触发
before: function(){}, //每个滚动动画开始时异步触发
after: function(){}, //每个滚动动画结束时触发
end: function(){} //滚动到最后一页时异步触发
});
});