A. django1.7部署到mod_wsgi进入admin的界面没有css样式,django自带服务器可以,怎么解决
拷贝此文件夹:python的安装路径\Lib\site-packages\django\contrib\admin\static文件到项目里面,在项目的setting文件中添加STATIC_DIRS=(这个文件夹所在的路径)即可
B. 中国有哪几种编程语言
目前比较流行的编程语言:
1、Ruby
Ruby于1993年2月24日开始编写至1995年12月才正式公开发布,一种为简单快捷面向对象编程而创的脚本语言,Ruby是一个语法像Smalltalk一样完全面向对象、脚本执行、又有Perl强大的文字处理功能的编程语言。
C. Django 的最佳开发实践有哪些
project结构
这里定义的是python开源项目目录结构中的$PROJ_NAME目录内的内容,需要与python开源项目目录结构结合起来。
PROJ_NAME/
__init__.py 这几个文件是django创建project所必须的,不做过多说明
manage.py
settings.py
urls.py
apps/ 即使是“小”工程,也建议分成多个app,每个app足够简单,只解决某一个方面的问题 (注1)
myapp1/
myapp2/
extra_apps/ 引用的其他app。
libs/ 加载第三方模块,可以避免版本冲突,按照标准的site-packages管理(注2)
python*.*/指定python版本号
site-packages/
requirements.pip #pip的依赖说明文件
tests/ project级别的测试,对于每个app,还要有自己的测试代码
static/ 静态内容
css/
js/
images/
uploads/ 上传文件所在目录
templates/ 模板目录,覆盖app的模板
flatpages/
comments/
example/
app1/
app2/
templatetags/ tag目录
注1:指定app加载,在settings.py中设置:
sys.path.insert(0, os.path.join(PROJECT_ROOT, 'apps'))
sys.path.insert(0, os.path.join(PROJECT_ROOT, 'extras'))
sys.path.insert(0, os.path.join(PROJECT_ROOT, 'libs'))
注2:自定义libs的加载,在settings.py中设置:
sys.path.insert(0, '/{{MY_LIB)}/site-packages/*****.egg')
sys.path.insert(0, '/{{MY_LIB}} /site-packages/')
app目录结构
$APP_NAME/
tests/ app级别的测试代码
models/ 注1
__init__.py
Amodels.py
Bmodels.py
templates/ 注2
templatetags/ tag目录
注1:如果很好的控制app的规模,Model类数量少,可以使用惯用的models.py文件中, 否则将models做成一个package
接下来可以有两种做法:
1. 在__init__.py中import所有的Model类
2. 指定Model的元类(Meta)的app_label
D. 中国那种编程语言最受公司欢迎
目前比较流行的编程语言:
1、Ruby
Ruby于1993年2月24日开始编写至1995年12月才正式公开发布,一种为简单快捷面向对象编程而创的脚本语言,Ruby是一个语法像Smalltalk一样完全面向对象、脚本执行、又有Perl强大的文字处理功能的编程语言。
E. 怎么Django标签过滤
1.创建一个模板库
使用模板过滤器的时候,直接把过滤器写在app里,
例如:在app里新建一个templatetags的文件夹,这个目录应当和 models.py 、 views.py 等处于同一层次。例如:
books/
__init__.py
models.py
templatetags/
views.py
在 templatetags 中创建两个空文件:一个 __init__.py (告诉Python这是一个包含了Python代码的包)和一个用来存放你自定义的标签/过滤器定义的文件。第二个文件的名字稍后将用来加载标签。例如,如果你的自定义标签/过滤器在一个叫作 poll_extras.py 的文件中,你需要在模板中写入如下内容: {% load poll_extras %}
{% load %}标签检查 INSTALLED_APPS 中的设置,仅允许加载已安装的Django应用程序中的模板库。
要成为有效的标签库,模块必须包含一个模块级的变量: register ,这是一个 template.Library 的实例。这个 template.Library 实例是包含所有已注册的标签及过滤器的数据结构。因此,在模块的顶部位置插入下述代码:
fromdjangoimport template
register = template.Library()
F. 学什么编程语言比较好
我应该学什么语言?这句话被问的很多,但是通常是不会得到答案的。每种语言都有一个相对固定的崇拜者群体,每次在论坛上有人比较一种语言的好坏,就会引发一场持久的战争。之所以发生这种情况,正是因为各种编译语言之间的力量是均衡的,没有哪一种语言是完美的,能够“终结”其它的所有语言。即使像Linux下的几种脚本语言那些看似长的很像的语言,也没有谁被谁完全替代,大家和平共处了许多年,并且在各自的位置发挥着自己的长处。这里就我所了解的几种语言和自己学习的经历给新人一点建议,如果你有特殊的需求,比如工程或者数学,那可能需要一些特殊的语言来解决,比如Lisp或者Ada,这在该领域内基本上是无可替代的,那你也没有什么好迷惘的了。如果你只是一个刚刚准备进入编程这一行的学生,或者是一个想业余时间搞点自己的小东西的业余开发者,却不知道哪种语言比较适合自己,就接着往下看吧。首先是C语言。几乎所有的书和计算机专业都把C语言称为语言中基础的基础,在大学里基本上都属于必修课程,而且,现在还是我们国家计算机等级考试和程序员水平与资格考试的标准语言。C语言之所以有这样的地位,是因为它最接近底层,最接近汇编语言和机器语言,最接近机器的思维方式,其它更高级的语言,最终也要按照它的那些基本逻辑来处理问题。所以,学好C语言可以更方便的以机器的模式思考问题。另外,C语言所涉及到的程序的顺序结构循环结构和分支结构,还有整数字符串数组等变量,这些都是万物之源,所有的编程语言都离不了。而且C语言有着严格的格式规范,不符合规范的写法或者错误的类型定义,都会引起编译错误,还有像if(a=1)这种常见错误,都可以让人在使用C语言的过程中养成良好的编程风格和代码规范。这些习惯在以后使用其它更宽松的语言的时候,会大大提高你的代码质量。还有,因为C最接近底层,其代码效率只有手工优化的汇编可以匹敌,在许多脚本语言里面(比如Python)可以把一些大运算量的关键代码用C来完成,从而获得更高的执行效率。综上所述,如果你真的想学好编程语言,C是一定要好好学的。但是新手学C语言通常会出现一个问题,就是除了写个排序算法,似乎根本想不出来C语言有什么用。这是因为我们的教科书讲C语言的时候,只讲这些基本算法,甚至连读写文件都不去讲,更不用说图形界面处理了和网络操作了,没有这些知识,想写一个真正的应用那是不可能的。不过,书上没有不等于学不了,文件操作和网络操作的讲解网络上有着大把的讲解,(现在Windows下用这个人比较少了,但是讲解Linux下C语言编程的书还是相当多的。)只要你随便找几篇文章看看,具备了这些基础知识,写一个自己的WEB服务器并不难。在逐步增加功能完善功能的同时,你的C语言基本上就可以达到相当牛人的水平了。从0开始学习C的成本是比较高的,如果没有明师(或者一本好书)的指点,某些概念想开窍也有些困难。但是你一旦突破了C语言这个障碍,再学习其它的语言,学习的曲线将会大为平坦。除了C语言以外的其它流行的高级语言,不管是编译语言还是脚本语言,基本上都是面向对象的语言了,所以你要搞清楚面向对象的概念。真正适合理解面向对象的语言,以前是SmallTalk,它是完全面向对象的,但是这个语言在中国很少见,书也很难买,现在,你可以学Ruby。(Ruby的作者是日本人,因此在许多论坛上提到它的时候会被许多愤青跳出来乱骂,这种做法是极其愚蠢的),近年新出来的Linux发生版里面都自带了Ruby支持,这已经充分说明了它在Linux管理方面的地位。而Ruby On Rails这个名字,更成了Web2.0快速开发的代名词。该语言借鉴了其它许多语言的特点,并且写出了自己的特点。在Ruby里,所有的东西都是对象,包括一个数字,你可以调用-1.abs这样的方法。一切都是对象,才能让你真正的理解面向对象。一旦你掌握了Ruby的思想和面向对象的设计方法,那么使用Ruby on rails来开发一个网站将变得极其轻松,因为该框架已经包装了WEB开发中用到的前后台的功能,所有的数据库读写都通过你的对象自身来完成,前台HTML的生成有着完整的模板系统,只要把美工给你的HTML代码里面的内容换成你的变量就OK了。如果你拥有了C语言的根本,和面向对象的思维方式,那么,如果因为工作需要,要去学习Java或者C#,那都是相当简单的事情。至于Perl和Python,本身跟Ruby的语法就比较接近(Perl要复杂一些,稍后再说)。但是目前你所学习的C语言和Ruby,都不适合用来开发Windows桌面程序,如果有这个需求,目前最简单的语言应该就是C#或者VB.Net了。通过简单的拖放控件就可以摆出相当专业的软件界面,而程序本身要实现的功能也无非就是本地的文件处理和数据库处理,只要了解了该功能所在的命名空间和几个基本的函数,再查阅一下MSDN,写程序轻轻松松。(以前使用最广的是VB6,不过现在Windows已经全面迁移到了.Net平台,已经基本没有必要再去学习VB6了。)当然,如果你不喜欢.Net平台,还可以选择Delphi或者C++。C++通常被认为是更高级的C,但是实际上它们的差别很大。而C++用来写桌面程序,无非也就是调用一些已经被包装好的处理窗体的函数而已。(C也可以调用,只是比较麻烦一些罢了。)Delphi的语法需要一段时间来适应,但是Delphi的开发工具跟Visual Studio一样简单,大部分操作拖放控件就OK。如果是在Linux下面,也有不错的C++的IDE和开发库用来开发桌面程序。C++入门容易升级很难,没有个三五年的潜心研究,是没有办法精通它的精髓的。但是既然你已经学到了这一步,那你应该已经很明白自己需要学哪些东西了,只要去找书,找好的源代码来研究就行了。Java语言的崇拜者很多,不得不单独拿出来说。Java语言的爱好者喜欢在语言层面把Java和C++相比,而不屑于跟C#来比较,而在企业开发架构方面(特别是B/S方面),又拿Java和.Net来做比较,因为C++缺乏这方面的应用。Java语言本身是非常干净的,但是被各种各样的包搞的比较混乱,新手进来容易摸不着头脑,而且框架太多,又互不兼容,习惯了Struts开发方式的人员,很可能在换了一家公司的以后,虽然Java很熟练,但是却不得不又要花很长的时间来研究学习和适应另一种开发框架。(.Net也在向这个趋势发展了,而像Ruby on Rails这种框架,则保证了框架的统一性,程序员的学习成本降低,企业的培训成本和维护也更低了。)Java通常被认为适合用来开发超大型的B/S项目,而一般的脚本语言则被认为只适合小型的项目开发,通常,这种问题都是由于开发工具的限制带来的。.Net平台如果不是因为Visual Studio这样方便而优秀的开发工具,不可能取得今天的成就。而大部分脚本语言则没有这个优势,缺少大型项目的管控能力,使得代码量始终保持在一个比较低的水平。但是像Python这样的代码,可以凭借良好的代码设计,模块间松散耦合,做出极其灵活而且大型的项目(比如YouTube)。Perl语言在Linux的系统维护方面有着不可动摇的地位,大量的系统维护代码都是Perl语言写的(而且php流行之前,WEB的CGI基本上也是以Perl语言为主的)。Perl在文本处理方面有着强大的能力,其正则表达式的处理方式更是成了其它语言必须兼容的标准。正则表达式的学习难度比较高,要想达到灵活运用的水平,需要大量的练习。(但是如果只是要达到基本的通用就行的水平,那还是相当简单的。)而在WEB开发方面还有一个重要的语言不可不提,那就是PHP。PHP出现的目标就是提供更方便的网站开发的能力,它的语法跟其它的脚本语言比如Perl/Python/Ruby都很接近,而且提供原生的Mysql数据库支持,读写数据库即简单又高效,而且因为Apache的良好支持,才使得LAMP平台能够与Java和.Net平台相抗衡,而且成为了小型项目首选的解决方案。至于SQL,我并没有拿它当一门语言来算,它只是你在做数据库编程的时候所需要的一种工具罢了,就跟调用其它的系统函数没有什么区别。简单的SQL语法无非就是插入删除选择更新四种操作。处于同样地位的还有HTML/CSS/Javascript,如果做WEB开发,这三种东西是必须要了解的,当然,前两种你可以不必精通,因为有美工来负责,而JavaScript属于完整的编程语言范畴,通常的美工是没有办法熟练掌握的,还是需要程序人员的搞定。但是Javascript的难度,在这个阶段大概只有学习Ruby的十分之一了,想学,很快就可以掌握。(PS:Javascript也是一门易学难精的语言,好的JS框架全世界也就那么几个人能写的出来,比如prototype,jquery,extjs)。程序语言多种多样,但是编程的思想却是不变的,而像设计模式、程序架构这种东西,都是语言无关的。一个开发项目,前阶段的需求分析,项目分析,直到概要设计阶段都是语言无关的,而项目设计期间使用的UML图也做到了尽量抽象,和具体的实现语言无关。直到详细设计和编码的时候,才需要针对不同的语言的特点做些调整,而它们提供的功能则是完全一致的。作为一个好的程序员,需要的不是编码的能力,而是需求分析和项目设计的能力,用哪种语言来实现则是可以随机应变的,只要掌握了具体语言的学习方法,熟练掌握一门语言并不需要太长的时间。因此,在经过了最初的语言学习的阶段之后,程序设计人员需要尽快的向下一个阶段演变,对设计模式的学习和理解是一个长期的过程,需要大量经验的积累,并经常的总结经验,从经验中归纳出自己常用的模式。作为程序员,还要有精益求精的态度,在时间允许的情况下,时常反思自己的作品,寻找更好的解决方案,在浏览网站学习的过程中,时刻以自己的项目为思考的对象,当发现更好的方法的时候,使用恰当的工具和方法来重构自己的项目。在这样不断进步的过程中,你就已经不再局限于一个普通的程序员了。只有C和C++没有C+
可以先学C在学C++在学C#
这是一条不错的路线~
想专业点的话的话先学C再C++再JAVA,C#,其余的如VB,pascal跟着学就可以了
要是写一些小程序的话C和VB是比较常用的,JAVA也可以,不过那是解释型的。一般用在网上(写网页的还有html,asp,php等)。不过Java是比较新的语言,潜力很大,据说以后95%的程序会用它来写,手机上的小游戏一般都是用它写的。其实他用来写小游戏也不错,如robotcode之类,不需要很深的专业知识,比较容易上手。
一般会C跟Java就差不多了,C是必须要学的,经典且强大,C++基本可由Java代替
昨晚封了两个网段的IP,124.115.0.*和124.115.1.*,终于解决了服务器这两天来的经常莫名其妙的停止响应的问题。网站的流量现在并不是很大,而且大部分页面的逻辑也很简单,但是最近两天经常出现网站没有反应,一直显示在等待,打不开页面。远程登录服务器速度也非常慢,基本上很难操作,查看进程发现django多出了很多子进程,这说明有些进程堵塞在那里,无法返回所以启动了新的子进程。给mysql数据库启用了slow-log以后,日志里经常会出现一些简单的查询语句,直接把语句放到mysql客户端里去执行,速度却相当快,估计是因为mysql并发量太大,导致这些简单的语句也无法顺利执行,所以把所有的网站页面都堵死了。后来查看网站的访问日志,好家伙,已经1.5个G的日志了,这个样子在这种速度下也没办法查看,于是清空了日志,稍等了一会,很快就超过了100K,打开一看,sosospider的名字映入眼帘。N多个来自不同IP的soso蜘蛛同时抓取portal页面,即便文章页已经启用了缓存也不起作用。于是赶紧停了网站,到lighttpd设置里封了soso的这两个网段,顺便封了网易有道的一个蜘蛛IP,虽然并发没有soso这么大,但是每隔几条日志里就有一条是网易有道的。拜托腾讯soso的开发兄弟们,不会写程序别乱写,写出这种程序来还放出来咬人,会给人家造成切实的经济损失的。有趣的是,在soso里面搜索soso蜘蛛,出来的全是soso蜘蛛因为乱抓网站被站长封杀的新闻,soso还真是大公无私啊,绝对没有屏蔽自己的负面新闻。Django的最佳系统结构
Django也用了一段时间了,写了两三个小网站,但是始终感觉自己写出来的站点目录和功能的安排还是比较混乱,很难达到让自己满意的效果,更不要说令人赏心悦目了。尤其是,当你需要开发下一个网站的时候,虽然感觉用户部分的功能(注册/登录/忘记密码/修改用户信息)所有的网站是通用的,但是想复用现有网站的这个功能却相当困难,居然笨到只能把模板文件/Model/View挨个复制过去再修改,实在是难登大雅之堂。于是狠命的研究了一些文章,终于算是找到了点前人的经验之谈,大概的总结如下:项目文件manage.py/urls.py/settings.py尽量少的改动(当然,不改动也是不可能的),setting.py里面需要设置数据库的相关信息,还有模板目录之类的,模板目录是可以使用相对目录的(使用os.path),很可惜,我没有测试成功,在lighttpd下面它仍然使用相对目录来搜索模板,所以总是报错,但是我找到了另一种解决方案。
setting.py里面有一个配置选项TEMPLATE_LOADERS。默认情况下它使用两种加载机制,第一种是文件系统方式,即使用下面配置的TEMPLATE_DIRS目录,在里面寻找模板文件,如果没有找到,第二种是app模式,它会在INSTALLED_APPS所标识的已安装的App下面寻找templates目录,并在其中寻找模板文件。而这个第二种,跟TEMPLATE_DIRS是无关的。因此,只要注释掉第一行,TEMPLATE_DIRS这个选项就可以留空了。然后,在任意一个App目录下面建一个templates目录,把模板文件扔进去就OK了。当然,最佳方案是,每个Apps下面放它自己用到的模板文件。这样,以后将这个App放进其它的项目的时候,你不需要做任何设置,模板这一块就已经正常工作了。
然后是Urls,在每个App下面添加它自己的urls.py文件,在里面设定它所用到的url映射,然后在项目级的urls.py里面使用include方式加载各个App的url配置就可以了。但是这样有一个要求,就是这个App要使用统一的目录前缀,比如用户相关的Url都以user/开头。(我不知道是不是必须这样,但是目前我所掌握的知识,只能这样了。)
通过这两个改动,已经将App和项目的耦合性降到了最低,现在如果要重用一个App,比如用户部分,只要把user目录拷到另一个项目,在settings中安装这个App,在urls.py中include这个App的urls,就OK了。至少里面所有的功能都是正常可用的。(当然,模板文件可能需要针对新的项目做些改动,但是如果你的模板设计规则是相同的,那么只要在新项目的framework里使用相同的内容,而使用另一种不同的style文件就可以了。)花了不少时间把理财易的代码整理了一遍,整理了一下功能的组织,把用户部分/留言板/日记本/投票以及站内信/好友/圈子(这三个功能在理财易中没有开放)全部建成单独的App,并分离了Urls和模板,虽然导致项目目录下面的子目录多了很多,但是每个目录的功能都简单明白了很多,可以很方便的添加或者移除某个App,比如圈子或者站内信,只要在配置文件中安装该App,相应的页面上添加链接,该功能就变得马上可用了。最基本的理论就是这样,剩下还有一些高级技巧,比如:每个App下面都可以建一个叫sql的目录,里面建立对应于model名称的sql文件,那么,在执行了syncdb命令安装该App以后,这个SQL文件就会被自动调用,可以用来往分类表里插入系统默认的分类,或者往用户表里插入一条最高权限的初始用户等等。
每个App下面都可以建一个叫templatetags的目录,在里面添加template tags和filters,大家互不干扰。
每个App下面都可以建一个叫tests的子目录,里面放一些单元测试的代码,就可以直接对该App进行单元测试。
每个App下面都可以建一个叫management.py的文件,里面可以放任意的Python函数,并给该函数添加事件接口声明,比如dispatcher.connect(my_syncdb_func, signal=signals.post_syncdb),这样就可以在App安装完成的时候执行任意的功能。(注意,是在添加了任何一个App以后都会被调用到,而不止是自己被安装以后。)
还有,每个App下面的views.py不是必须的,你可以按照自己的需求把函数拆解到多个python文件中,只要在urls.py中引用了正确的类名就可以了。这对于一个功能比较多的App是相当有用的。
有了这些属性的帮忙,基本上你可以对自己的项目文件做出各种适合自己的调整,并且仍然保持项目结构的优雅,并且,对于程序的执行效能是完全没有影响的。希望这篇文章对于Django的用户起到一点帮助。
G. 第10节、案例-客户关系管理系统之增删改查笔记
第10节、案例-客户关系管理系统之增删改查笔记
一、建立模型
1、导入模型
fromdjango.dbimportmodels
2、创建学生表
classStudent(models.Model):# 学生表
name=models.CharField(max_length=20)
age=models.SmallIntegerField()
sex=models.SmallIntegerField(default=1)
qq=models.CharField(max_length=20,unique=True)
phone=models.CharField(max_length=20,unique=True)
c_time=models.DateTimeField(verbose_name='创建时间',auto_now_add=True)
e_time=models.DateTimeField(verbose_name='修改时间',auto_now=True)
grade=models.ForeignKey('Grade',on_delete=models.SET_NULL,null=True)
is_delete=models.BooleanField(default=False)# 一般实际开发过程中,我们不会直接删除数据,而是给数据加上is_delete字段,来标记数据的状态。
def__str__(self):
return'%s-%s-%s'%(self.name,self.age,self.sex)
3、创建学生详情表
classStudentDetail(models.Model):#学生详情表
num=models.CharField('身份证',max_length=40,unique=True)
college=models.CharField('毕业学校',max_length=20,default='')
student=models.OneToOneField('Student',on_delete=models.CASCADE,related_name='detail')
def__str__(self):
return'%s-%s'%(self.num,self.college)
4、创建班级表
classGrade(models.Model):# 班级表
name=models.CharField('班级名称',max_length=20)
num=models.CharField('班期',max_length=20)
def__str__(self):
return'%s-%s'%(self.name,self.num)
5、创建课程表
classCourse(models.Model):# 课程表
name=models.CharField('课程名称',max_length=20)
student=models.ManyToManyField('Student',through='Enroll')
def__str__(self):
return'%s'%self.name
6、创建学生表与课程表的中间表
classEnroll(models.Model):# 课程与学生多对多中间表
student=models.ForeignKey('Student',on_delete=models.CASCADE)
course=models.ForeignKey('Course',on_delete=models.CASCADE)
pay=models.FloatField('缴费金额',default=0)
c_time=models.DateTimeField(verbose_name='创建时间',auto_now_add=True)
def__str__(self):
return'%s'%self.pay
##
二、增删改查功能实现
1、index页面视图函数
fromdjango.shortcutsimportrender,redirect,reverse
fromdjango.httpimportHttpResponse
fromstudent.modelsimportStudent,Grade,StudentDetail
fromdjango.db.modelsimportQ
fromdjango.core.paginatorimportPaginator
# Create your views here.
defindex(request):
section='学生列表'
search=request.POST.get('search','').strip()# 接收从html的form表单传过来的参数
ifsearch:
ifsearch.isdigit():# 如果是数值类型则
sts=Student.objects.filter(Q(qq=search)|Q(phone=search),is_delete=False)# 用qq和phone去匹配
else:# 如果是字符型
sts=Student.objects.filter(name=search,is_delete=False)# 则和名字匹配
else:# search都没有匹配到则查询所有学生
sts=Student.objects.filter(is_delete=False)
sts=sts.order_by('-c_time')# 排序
returnrender(request,'student/index.html',context={
'sts':sts,
'section':section,
'search':search,
})
2、学生删除页视图
defstudent_delete(request,pk):
student=Student.objects.get(pk=pk)# 查询id为pk的学生
student.is_delete=True# 将is_delete标记为True,
student.save()# 保存
returnredirect(reverse('student:index'))
3、学生详情页视图
defstudent_detail(request,pk):
section='学生详情'
grades=Grade.objects.all()# 查询所有班级
sts=Student.objects.get(pk=pk)# 获取当前id为pk的学生信息
grade=Grade.objects.get(pk=sts.grade_id)# 查询指定学生的班级
detail=StudentDetail.objects.get(student=sts)# 查询指定学生的详情
returnrender(request,'student/student_detail.html',context={
'section':section,
'grades':grades,
'sts':sts,
'grade':grade,
'detail':detail,
})
4、添加页视图函数
defstudent_add(request):
section='添加学生信息'
grades=Grade.objects.all()# 获取所有的班级
ifrequest.method=='GET':
returnrender(request,'student/student_detail.html',context={
'section':section,
'grades':grades,
})
ifrequest.method=='POST':
# 获取班级信息
grade_id=request.POST.get('grade')# 获取前端传回来的grade.id
try:
grade=Grade.objects.get(pk=grade_id)
except:
grade=None
# 获取学生信息姓名、年龄、性别、qq、电话
data= {
'name':request.POST.get('name'),
'age':request.POST.get('age'),
'sex':request.POST.get('sex'),
'qq':request.POST.get('qq'),
'phone':request.POST.get('phone'),
'grade':grade#表关联,在student中
}
student=Student.objects.create(**data)
# 获取学生详情信息
StudentDetail.objects.create(
num=request.POST.get('num'),
college=request.POST.get('college'),
student=student# 表关联
)
returnredirect(reverse('student:index'))
5、修改学生信息页视图函数
defstudent_edit(request,pk):
section='修改学生信息'
sts=Student.objects.get(pk=pk)# 查询id为pk的学生
grade=Grade.objects.get(pk=sts.grade_id)# 查询指定学生的班级
detail=StudentDetail.objects.get(student=sts)# 查询指定学生的详情
ifrequest.method=='GET':
returnrender(request,'student/student_detail.html',context={
'section':section,
'sts':sts,
'grade':grade,
'detail':detail,
})
ifrequest.method=='POST':
# 获取班级信息
grade_id=request.POST.get('grade')# 获取前端传回来的grade
try:
grade=Grade.objects.get(pk=grade_id)# 获取学生的班级
except:
grade=None
# 获取学生信息并修改
student=Student.objects.get(pk=pk)
student.name=request.POST.get('name')
student.age=request.POST.get('age')
student.sex=request.POST.get('sex')
student.qq=request.POST.get('qq')
student.phone=request.POST.get('phone')
student.grade=grade# 表关联
# 获取学生详情
try:
detail=student.detail# 表关联,关联表在student
except:
detail=StudentDetail()
detail.student=student# 表关联,关联表在detail
detail.num=request.POST.get('num')
detail.college=request.POST.get('college')
detail.save()# 保存
student.save()# 保存
returnredirect(reverse('student:index'))
三、分页功能实现
1、对主页分页方法一
1.1主页的视图函数
defindex(request):
section='学生列表'
search=request.POST.get('search','').strip()# 接收从html的form表单传过来的参数
ifsearch:
ifsearch.isdigit():# 如果是数值类型则
sts=Student.objects.filter(Q(qq=search)|Q(phone=search),is_delete=False)# 用qq和phone去匹配
else:# 如果是字符型
sts=Student.objects.filter(name=search,is_delete=False)# 则和名字匹配
else:# search都没有匹配到则查询所有学生
sts=Student.objects.filter(is_delete=False)
sts=sts.order_by('-c_time')# 排序
# 分页
total_num=sts.count()# 总的数据量
per_page=int(request.GET.get('per_page',5))# 每页默认条数为5
page=int(request.GET.get('page',1))# 当前页面默认为第1页
p=Paginator(sts,per_page,allow_empty_first_page=True)
sts=p.get_page(page)# 每页显示的数据
total_page=p.num_pages# 总的页面数
page_list=p.page_range# 获取页面范围
returnrender(request,'student/index.html',context={
'sts':sts,
'section':section,
'search':search,
'total_num':total_num,
'total_page':total_page,
'page':page,
'per_page':per_page,
'page_list':page_list,
})
1.2、html中页码的设置
<navaria-label="Page navigation"style="display: inline-block">
<ulclass="pagination">
<li{%ifpage==1%}class="disabled"{%endif%}>
<ahref="{% if page > 1 %}{% url 'student:index' %}?page={{ page|add:-1 }}&per_page={{ per_page }}{% else %}{% url 'student:index' %}?page={{ page }}&per_page={{ per_page }}{% endif %}"aria-label="Previous">
<spanaria-hidden="true">上一页</span>
</a>
</li>
{% for i in page_list %}
<li{%ifpage==i%}class="active"{%endif%}><ahref="{{ request.path }}?page={{ i }}&per_page={{ per_page }}">{{ i }}</a></li>
{% endfor %}
<li{%ifpage==total_page%}class="disabled"{%endif%}>
<ahref="{% if page < total_page %}{% url 'student:index' %}?page={{ page|add:1 }}&per_page={{ per_page }}{% else %}{% url 'student:index' %}?page={{ page }}&per_page={{ per_page }}{% endif %}"aria-label="Next">
<spanaria-hidden="true">下一页</span>
</a>
</li>
</ul>
</nav>
<!-- Single button -->
<divclass="btn-group"style="display: inline-block; margin-top: -68px">
<buttontype="button"class="btn btn-default dropdown-toggle"data-toggle="dropdown"aria-haspopup="true"aria-expanded="false">
{{ per_page }}条/页<spanclass="caret"></span>
</button>
<ulclass="dropdown-menu">
<li><ahref="{% url 'student:index' %}?page={{ page}}&per_page= 5 ">5条/页</a></li>
<li><ahref="{% url 'student:index' %}?page={{ page}}&per_page= 10 ">10条/页</a></li>
<li><ahref="{% url 'student:index' %}?page={{ page}}&per_page= 15 ">15条/页</a></li>
<li><ahref="{% url 'student:index' %}?page={{ page}}&per_page= 20 ">20条/页</a></li>
</ul>
</div>
2、对主页分页方法二(利用包含标签)
2.1、index中的视图函数
defindex(request):
section='学生列表'
search=request.POST.get('search','').strip()# 接收从html的form表单传过来的参数
ifsearch:
ifsearch.isdigit():# 如果是数值类型则
sts=Student.objects.filter(Q(qq=search)|Q(phone=search),is_delete=False)# 用qq和phone去匹配
else:# 如果是字符型
sts=Student.objects.filter(name=search,is_delete=False)# 则和名字匹配
else:# search都没有匹配到则查询所有学生
sts=Student.objects.filter(is_delete=False)
sts=sts.order_by('-c_time')# 排序
# 分页
total_num=sts.count()# 总的数据量
per_page=int(request.GET.get('per_page',5))# 每页默认条数为5
page=int(request.GET.get('page',1))# 当前页面默认为第1页
p=Paginator(sts,per_page,allow_empty_first_page=True)
sts=p.get_page(page)# 每页显示的数据
total_page=p.num_pages# 总的页面数
page_list=p.page_range# 获取页面范围
returnrender(request,'student/index.html',context={
'sts':sts,
'section':section,
'search':search,
'total_num':total_num,
'total_page':total_page,
'page':page,
'per_page':per_page,
'page_list':page_list,
})
2.2、在templatetags文件夹中创建student_custormer_tags.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
# author:cyb time:2019/5/25 23:34
fromdjangoimporttemplate
register=template.Library()
@register.inclusion_tag('student/paginitor.html',takes_context=True)
defpagination_html(context):# 谁引用就导入谁的context
total_page=context['total_page']# 总的页面数
page=context['page']# 显示第几页的数据
page_list=context['page_list']# 页面范围
per_page=context['per_page']# 每页条数
'''
假设现在total_page = 6
两种页码控制方法:
当num = 1 # 当前页面左右各有几页
上一页 1 2 3 下一页
上一页 4 5 6 下一页
上一页 1 2 下一页
上一页 5 6 下一页
当num = 2 # 当前页面左右各有几页
上一页 1 2 3 下一页
上一页 1 2 3 4 下一页
上一页 1 2 3 4 5 下一页
上一页 2 3 4 5 6 下一页
上一页 4 5 6 下一页
'''
page_list= []
num=2
# 1、左边 + 当前页显示的页码列表
# 1.1、左边不够显示时,页码范围1到当前页
ifpage-num<=0:
foriinrange(1,page+1):
page_list.append(i)
else:# 左边够显示时,页码范围page-num到当前页
foriinrange(page-num,page+1):
page_list.append(i)
# 2、右边 + 当前页显示的页码列表
# 2.1、右边不够显示时,页码范围当前页到total_page
ifpage+num>=total_page:
foriinrange(page+1,total_page+1):
page_list.append(i)
# 2.2、右边够显示时,页码范围(当前页+1)到(当前页+num)
else:
foriinrange(page+1,page+num):
page_list.append(i)
return{
'total_page':total_page,
'page':page,
'page_list':page_list,
'per_page':per_page
}
2.3、在app中新建一个包含标签渲染模板paginitor.html
<ulclass="pagination">
<li{%ifpage==1%}class="disabled"{%endif%}>
<a{%ifpage>1 %} href="{% url 'student:index' %}?page={{ page|add:'-1' }}&per_page={{ per_page }}{% endif %}" aria-label="Previous">
<spanaria-hidden="true">«</span>
</a>
</li>
{% for page_num in page_list %}
<li{%ifpage_num==page%}class="active"{%endif%}><ahref="{{ request.path }}?page={{ page_num }}&per_page={{ per_page }}">{{ page_num }}</a></li>
{% endfor %}
<li{%ifpage==total_page%}class="disabled"{%endif%}>
<a{%ifpage< total_page %} href="{{ request.path }}?page={{ page|add:'1' }}&per_page={{ per_page }}{% endif %}" aria-label="Next">
<spanaria-hidden="true">»</span>
</a>
</li>
</ul>
2.4、在index.html中导入后在对应位置引用
1、导入:{% load student_customer_tags %}
2、引用:
<nav aria-label="Page navigation" style="display: inline-block">
{% pagination_html %}
</nav>
四、页面展示
1、主页展示
2、添加页展示
3、修改页展示