Django基础笔记
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django基础笔记相关的知识,希望对你有一定的参考价值。
django随记:
Django URL配置原则:松耦合原则,松耦合是一个重要的保证互换性的软件开发方法。
例如urls.py 是用来配置url的 views.py是用来配置视图函数的,二者之间是松耦合的!
Django中时区的设置, 在Django中加入在/home/zhou中通过django-admin.py startproject mysite创建一个mysite的应用
此时在/home/zhou文件夹下会生成一个manage.py文件,同时会有一个mysite的文件夹。 manage.py所在的目录会自动被加入进python的path. 这个设置对于整个python工程有效
mysite文件夹下的文件如下:
__init__.py
urls.py
settings.py
wsgi.py
自己添加部分文件后次文件如下所示:
__init__.py
models.py --
views.py --
settings.py
wsgi.py
templates (模板文件夹)
settings.py内时区设置:默认的时区为TIME_ZONE="America/Chicago"修改为TIME_ZONE="Asia/Shanghai"北京时区。
2015sjgc1314
USE_TZ=False (若不这样设置, 结果数据库主动填充的还是错了8个小时!)
LANGUAGE_CODE="zh-CN" 可以使djangoadmin变成中文版本
django中捕获get中参数:
从技术上说,所捕获值总是unicode objects,而不是简单的str
举例如下:
urls.py中 r"^time/(\\d+)",timeAhead
views.py中:
def timeAhead(request,dt):
pass
django中模板的设置在:
例如:mysite应用中设置template文件夹为 templates
settings.py中
TEMPLATE_DIRS=(os.path.join(os.path.dirname(__file__),"templates"),)
且可以添加多个目录。
8.214 [email protected]#$!&$%UJNAV
进入django的shell:
python manage.py shell可以进入django的shell终端,在此终端内可以对django的模板系统进行练习,其是按照setting.py中的配置进行启动的,其依赖于配置文件
一:关于正则表达式
^匹配开始
$匹配结束
^hello/$仅仅对hello/进行匹配
^hello 对以hello开头的所有字符串进行匹配
.任意单个字符
\\d任意一位数字
[a,z]a-z中任意一个
[A-Z] A-Z中任意一个
[a-zA-Z]a-z中任意一个,且不区分大小写
+ 匹配一个或更多 \\d+
? 匹配0个或1个 \\d+
{1,3} 匹配1-3个
()小括号用来括起来的部分会被提取出来。用来提取字符串。例如
url(r"hello/(\\d{1,2})/",views.num)
二:django模板系统:
模板通常用于产生html,但是django的模板也能够产生任何给予文本格式的文档。
template.Template类用于产生模板
template.Context类用于产生上下文环境,类似于python的字典数据类型。
举例:
from django import template
t=template.Template("my name is {{name}}")
c=template.Context({"name":"zhou"})
print t.render(c)
{{name}} name为变量
{%if name%} if name 为模板标签 类似的还有for item in itemlist模板标签。
django模板系统举例2:
from django import template
t=template.Template("my name is {{name.upper}}")
c=template.Context({"name":"abcd"})
print t.render(c)
类似的还有
templaget.get_template("index.html")
1. 在django的模板系统中是支持方法调用或属性调用的。 当然其是无法传入参数的。 仅仅可以调用无参数的方法或者普通属性。 调用是要注意,避免delete方法。 这样会导致异常。
如果用t.render(template.Context())
方法进行渲染时, 结果为my name is 变量不会显示。
同时.也可以进行列表索引。
例如name.1 将会用列表的第一个元素
如果为name.abc
此时系统会按照如下顺序进行查找:
字典类型查找: name["abc"]
属性查找:name.abc
方法查找:name.abc()
列表索引查找: name[abc]
利用模板进行方法调用时要注意:如果此方法引发一个异常会导致整个页面抛出异常,除非该异常有一个属性silent_variable_failure属性,并且值为True
如果一个变量不存在,模板系统会把它展示位空字符串。不做任何事情来表示失败。
2.基本的模板标签和过滤器
if:
{%if name%}
...........
{%else%}
.....
{%endif%}
if可以和and or not配合使用。and or not不要混用 else是可选的。
for:
{% for item in list%}
..............
{%endfor%}
{% for item in list reversed %}
..............
{%endfor%}
django不支持退出循环,如果想要退出循环,可以改变正在迭代的变量,让其仅仅包含需要迭代的项目
在每个{% for %}循环内部有一个成为forloop的模板变量,这个变量有一些提示循环进度信息的属性。
{%for item in todo_list%}
<p>{{forloop.counter}}:{{item}}</p>
{%endfor%}
类似的变量还有forloop.counter0
forloop.revcounter
forloop.revcounter0
forloop.first
forloop.last
ifequal:
{%ifequal a "abc"%}
....
{%else%}
........
{%endifequal%}
ifnotequal:
{%ifnotequal a "abc"%}
.....
{%else%}
....
{%endifnotequal%]
3.注释:
{#this is a comment#}
4.过滤器
{{name|lower}} 显示的内容是变量name经过滤器处理过的结果。
5.常见的特殊符号的输出:
openblock {%
closeblock %}
openvariable {{
closevariable }}
openbrace {
closebrace }
opencomment {#
closecomment #}
{{bio|truncatewords:"30"}} 过滤器可以有参数。
最常用的过滤器:
addslashes:添加反斜杠到任何反斜杠、单引号或者双引号前面,这在包含javascript的文本时是非常有用的
length:返回变量的长度,列表、元祖、字符串均可。
django模板的理解:
from django import template
from django.template import context
a=template.Template("{{a}}悉知")
b=context.Context({"a":"郑州"})
c=a.render(b)
len(c) ----4 print c 郑州悉知
aa=template.Template(u"{{a}}悉知")
bb=context.Context({"a":"郑州"})
cc=aa.render(bb)
len(cc) ----4 print cc 郑州悉知
在django中可以做如下理解:
template.Template(args)会先把args转化为Unicode字符串(根据当前的文件的字符编码)
context.Context(args) 也会先把args转化为Unicode字符串(根据当前的文件的字符编码)
然后再django的模板渲染器(纯unicode环境)中进行渲染,最后返回一个类Unicode字符串。(其实就是Unicode字符串,只不过其归属类不是Unicode) 你可以轻易的用unicode() 把其转化为python的unicode字符串。
HttpResponse()或者render_to_response()等类似的,其实都是把unicode()转化为Utf-8返回给浏览器的。!
综上:
在html中要用utf8编码。
在python文件中要用Utf8编码
django的这些特性使得在网页中使用中文非常容易。 其总是返回给浏览器Utf8类型的Html, 其在内部渲染器总是unicode环境
三:模板的使用
from django.shortcuts import render
# Create your views here.
from django.http import HttpResponse
from django import template
from django.template.loader import get_template
from django.shortcuts import render_to_response
import datetime
def hello(request):
return HttpResponse(str(datetime.datetime.now()))
def num(requset,offset):
#temp=get_template("num.html")
#html=temp.render(template.Context({"num":123}))
#return HttpResponse(html)
return render_to_response("num.html",template.Context({"num":456}))
四:模板的继承
定义一个base.html文件
<html lang="en">
<title>{%block title%}hello world{%endblock%}
</title>
<body>
{{text}}
</body>
</html>
人后在extend.html中
{% extends "base.html"}
{%block title%}THE CURRENT TIME {% endblock%}
在使用的时候可以用render_to_response("entend.html",template.Context({"text":"hello world!"}))
五:模型
1.django中模型也就是和数据库相关的抽象。
django和数据库连接时和settings.py有很大关系。
其中例如django和mysql数据库进行连接的时候要配置好这个文件:
例如
DATABASES={
‘default‘:{
‘ENGINE‘:‘django.db.backends.mysql‘,
‘NAME‘:‘test‘,
‘USER‘:‘root‘,
‘PASSWORD‘:‘123456‘,
‘HOST‘:‘192.168.8.137‘,
‘PORT‘:‘3306‘,
}
}
注意: host部分最好要填ip地址,即便是本机!
测试是否设置正确了:
python manage.py shell
from django.db import connection
cursor=connection.cursor()
如果上面两个语句执行没有错误,那么数据库连接已经成功了。
2.在django中 项目--- 应用--
python manange.py startapp users
在项目中创建一个应用
user目录中的结构如下:
__init__.py
models.py
tests.py
views.py
models.py是用于创建应用的。 views.py是用于创建视图函数。
整个创建一个django项目的流程应该如下:
创建一个项目mysite在/home/zhou下
/home/zhou/mysite下面会存在
manage.py
mysite 文件夹
进入mysite文件夹
python ../manage.py startapp schoop
此时在/home/zhou/mysite/mysite下面会存在一个文件夹
school 内有__init__.py models.py tests.py views.py
对于settings.py文件一般要设置时区 TEMPLATE_DIRS INSTALLED_APPS DATABASES数据库 一切和路径相关的都是以manage.py所在位置为准的。
python manage.py sqlall school
3.from mysite.school.models import Teacher
a=Teacher(name="zhou",age=22)
a.save() #更新所有更该到数据库,记住,加入你仅仅改了某一列,其会更新所有列!
4.每一个模型,例如Teacher Student 都具有一个管理器,
Teacher.object 就是Teacher模型的管理器,
常用的如:
a=Teacher.object.all()
for i in a:
print i.name,i.age
b=Teacher.object.filter(name="zhou)
for i in b:
print i.name,i.age
c=Teacher.object.filter(name_contains="ou") #类似的还有name_icontains name_startwith name_endwith range等
d=Teacher.object.get(name="zhou") #返回耽搁对象,不是列表,如果结果是多个对象则会抛出异常,查询没有结果也会抛出异常
e=Teacher.objects.order_by("age") #“-age”表示逆序
for i in e:
print i.name,i.age
DecimalField
固定精度的十进制数,一般用来存金额相关的数据。对应python的Decimal,额外的参数包括DecimalField.max_digits 位数和DecimalField.decimal_places 小数位数 ,这个还是要参照一下mysql的Decimal类型,http://database.51cto.com/art/201005/201651.htm
例如:price = models.DecimalField(max_digits=8,decimal_places=2)
5.在Teacher模型下可以新建一个类class Meta来附加一些说明性的信息。
class Teacher:
*****
*****
class Meta:
ordering=[‘name‘]
表示在进行排序的时候order_by()函数会默认用"name"作为参数
6.连续查询
a=Teacher.objects.filter().order_by("age") #先查后排序
7.限制返回的数据
c=Teacher.objects.filter()[0]
8.更新多个对象
a=Teacher.objects.filter(name="li").update(name="wang")
update用于更新一个或多个对象的制定列
9.删除多个对象
a=Teacher.objects.filter()
a.delete()
__author__ = ‘Administrator‘
from django.db import models
class test(models.Model):
name=models.CharField(null=True,max_length=20)
name_1=models.CharField(null=False,max_length=20)
age=models.IntegerField(null=True)
age_1=models.IntegerField(null=False)
如果允许某一列字段为空可以按照如下的规则:
对于非日期、非数字型的来说(如CharField,FilePathField):
null=True 是用来指定此field可以为null ,当save时,不指定此filed则会插入null
null=Flase 是用来指定此field不可以为null,当save是,不指定此field则会插入‘‘
对于日期型、数字型的来说:
null=True 是用来指定此field可以为null, 当save时,如果不指定此field则会插入null
null=False 是用来指定此field不可以为null,当save时,如果不指定此field则会报错
blank的作用是指定在admin页面中这个字段是否可以不填。
Meta类常用的参数:
class Meta:
db_table="test_table"
verbose_name="test_table" #如 User model对应于————User,主要用于admin页面中
verbose_name_plural="test_tables" #如User model 对应于---- Users,主要用于admin页面中
每个APP中如果需要用到admin页面管理数据库的话,那么每个APP中都应该有一个admin.py的文件:
一个例子如下:
#coding:utf-8
__author__ = ‘python‘
from django.contrib import admin
from models import test,test_main
admin.site.register([test,test_main])
10. order_by的使用:
Teacher.objects.filter(***).order_by()
11. group_by的使用
result=Teacher.objects.filter(***)
result.query.group_by=["author"]
或者:
result=Teacher.objects.filter(***)
result.query.group_by=["author"]
queryresult=Querset(query=result.query,model=Teacher)
注意:第一种方式在author有空值得花,方式1会报错。
12 many-to-many字段filter时的用法
#yanfa=Group.objects.get(name="研发")如果想要筛选到 groups 为yanfa 并且为yunwei的用户。可以通过下面的链式搜索:
#User.objects.filter(groups=yanfa) many -to -many 字段的 filter的使用
User.object.filter(groups=yanfa).filter(groups=yunwei)
六:表单
1.从request中获取数据:
request.path 除域名以外的请求路径,以/开头 例如 /hello/
request.get_host() 服务器的域名或ip
request.get_full_path() 完整的的请求路径,带有get参数
request.is_secure() 客户端是否是通过HTTPS访问的
request.META是一个字典,起包含了所有本次HTTP请求的header信息,比如用户的ip地址,用户agent例如:
HTTP_REFERER 进站前链接网页
HTTP_USER_AGENT 用户浏览器user-agent字符串。
REMOTE_ADDR 客户端IP, 如果申请是经过代理服务器的话,它可能是一个以都好分割的多个IP地址。
12.111.67.89,23.22.22.22
request.META仅仅是一个普通的python字典,当试图访问一个不存在的键时会触发一个异常,这是一个用户提交的、不应该给予信任的额外的数据。
request.GET 是一个类字典,用来访问GET的数据,可能来自于form标签提交的,也可能是来自于url重的查询字符串
request.POST 是一个类字典,用来访问POST的数据,来自于form标签提交
username=request.GET.get("username")
username_list=request.GET.getlist("username")
当提交的表单仅仅需要获取数据时就可以用GET,而当我们提交表单时需要更改服务器数据的状态,或者说发送e-mail,或者不仅仅是获取并显示数据的时候就可以使用post.
例如:<form action="/test/" method="get">
<form action="" method="post">
在模板中使用request变量的方法:
TEMPLATE_CONTEXT_PROCESSORS模板处理器中加入:
"django.core.context_processors.request"
然后利用render_to_response("test.html",{"name":name},context_instance=RequestContext(request))
七:views.py url.py高级配置
1.在urls.py中可以这样设置:
urlpatterns=patterns(‘‘,
(r"^hello/$","mysite.views.hello"),
)
2.同样也可以这样设置:
urlpatterns=patterns(‘mysite.views‘,
(r"^hello/$",‘hello‘),)
urlpatterns+=patterns(‘yousite.views‘,
(r"^hello/$",‘hello‘),)
3.甚至可以这样:
urlpatterns=patterns(‘mysite.views‘,
(r"^hello/$",‘hello‘,{‘template_name‘:‘template1.html‘}),)
视图函数:
def hello(request,template_name):
pass
4.还可以这样:
urlpatterns=patterns("",
(r"^hello/(P?<id>\\d+)",hello,{"id":123}),)
在此情况下字典内的Id比捕获到的id的优先级高。捕获到的那个不起作用
(r"^robots\\.txt$",lambda request:HttpResponse("User-agent: *\\nDisallow: /",mimetype="text/plain")), #robots
八:template的高级进阶:
1.在模板的渲染中常用renter_to_response("index.html",{"name":name})等形式进行模板的渲染。
如果name中含有<b>li</b> 这一部分会直接被渲染出来,li被html解析, 这些<>符号被django转义了!
如果想要某个变量关闭这种转义特性有两种方法:
1.{{name|safe}}
2.{%autoescape off%} {{name}} {%endautoescape%}
2.django中可以通过配置settings.py中TEMPLATE_LOADER设置模板加载器
1.django.template.loaders.filesystem.load_template_source根据TEMPLATE_DIRS的设置从文件系统中加载模板,默认可用!
2.django.template.loaders.app_directories.load_template_source根据文件系统中django应用中加载模板,对INSTALLED_APPS中的每一个应用加载器会寻找templates子目录,若此目录存在,django就在那里寻找模板!
这两个最为常用,django按照TEMPLATE_LOADERS设置中的顺序使用模板加载器,它逐个使用每个加载器直到找到一个匹配的模板
和此很类似的就是STATICFILES_DIRS配置,
‘django.contrib.staticfiles.finders.FileSystemFinder‘,
‘django.contrib.staticfiles.finders.AppDirectoriesFinder‘,
第一个加载器代表从STATICFILES_DIR中寻找
第二个加载器代表从每个APP的static目录中寻找。
3.django直至自定义过滤器、自定义标签、等完成高级功能!!
自定义过滤器:
{{var|foo:"bar"}}
过滤器foo穿入了两个参数:
for(value,arg): var传到value "bar"传入arg.
大多数的过滤器是不需要参数的。
在school应用下新建一个目录:
templatetags
-- __init__.py
-- test.py
test.py中
from django import template
register=template.Libary()
@register.filter(name="cut")
def cut(value):
return value.upper
使用时模板中加上
{%load test%} 就开业使用cut过滤器了
自定义标签:
from django import template
class AtmCssNode(template.Node):
def __init__(self,path):
self.path=path
def render(self, context):
try:
request=context["request"]
return AtmFrame(self.path,request).get_css()
except Exception as e :
return str(e),"PATH:%s"%self.path
@register.tag("atmjs")
def atmjs_handle(parser,token):
try:
tag_name,path=token.split_contents()
except:
return ‘‘
else:
return AtmJsNode(path)
token.split_contents 用空格把其分开。 如果{% atmjs main %} . token为 atmjs main . 然后利用token.split_contents()函数将其分割为一个元组。
(自定义标签输出的值不会被转义!)
4.自定义处理器:
定义一个处理器:
#coding:utf-8
__author__ = ‘Administrator‘
from settings import DEBUG
from django.shortcuts import render_to_response
def custom_proc(request):
"自定义的处理器, 包含了 debug_status "
return {
"debug_status":DEBUG
}
加入到settings.py中
TEMPLATE_CONTEXT_PROCESSORS = (
"django.contrib.auth.context_processors.auth",
"django.core.context_processors.debug",
"django.core.context_processors.i18n",
"django.core.context_processors.media",
"django.core.context_processors.static",
"django.contrib.messages.context_processors.messages",
"django.core.context_processors.request",
"digger.context_processors.custom_proc"
)
九:models高级进阶:
1.模型中外键(ForeignKey)的作用
from django.db import models
# Create your models here.
class ScoreTable(models.Model):
yuwen=models.CharField(max_length=30)
shuxue=models.IntegerField()
class Info(models.Model):
name=models.CharField(max_length=30)
score=models.ForeignKey(ScoreTable)
python manage.py shell
>>from school.models import *
>>a=ScoreTable(yuwen="98",shuxue=90)
>>a.save()
>>b=Info(name="zhou",score=a)
>>b.save()
>>b.score.yuwen,b.score.shuxue
这就是外键的作用,外键用于存储一些详细信息。具有外键的表,必须外键已经建立才可以为这个表插入一些东西。
如上所示,要建立b必须要有a作为参数。
2.访问外键的值
b.score.yuwen
3.通过外键回溯
>>c=Info(name="zhou",score=a)
score作为一个外键,其对应了主表内的两行
>>e=ScoreTable.objects.get(yuwen="98",shuxue=90)
>>f=e.info_set.all()
>>for i in f: print i.name
zhou
zhou
结果输出了两行。
4.ManyToManyField的使用
对于上面的例子的深思:一个学生信息中有一个学生名字 一门课的成绩。
如果是一个学生信息中一个学生名字 多门课的成绩该如何应对?
简单来说 一个学生一个信息用ForeignKey
一个学生多个信息时用ManyToMany
举例子如下:
class Kemu(models.Model):
name=models.CharField(max_length=30)
value=models.IntegerField()
class StudentScore(models.Model):
name=models.CharField(max_length=30)
score=models.ManyToManyField(Kemu)
一般对于不含哟ManyToManyField的类,建立对象的时候参数必须要传递满,且正确。然后save
对于含有ManyToManyField的类必须要先不传参数,save,再添加数据,save
例如:
a=Kemu(name="yuwen",value=23)
b=Kemu(name="shuxue",value=24)
a.save()
b.save()
c=StudentScore()
c.save()
c.name="zhou"
c.score=[a,b]
c.save()
5.数据库中添加列
1.在模型中添加字段
2.manage.py sqlall youapp 查看模型新的CREATE TABLE语句,注意新字段的定义
3.进入数据库的交互命令界面执行ALTER TABLE语句增加新的列
4.manage.py shell验证新的字段是否被正确的添加。
6.数据库中删除列
1.在模型中删除字段
2.在数据库中删除对应列
十:会话、用户和注册
1.cookie中不应该存储一些过于敏感的信息!敏感的信息应该存储在session中
一般cookie默认为会话cookie
取:
a=request.COOKIES
print a["lover"]
存:
response=render_to_response("index.html")
response.set_cookie("lover":"baby")
return response
cookie的存取大概就是这样
在set_cookie中有许多可选的参数
max_age cookies的持续有效时间,默认为None
erpires cookies的过期时间,默认为None
path cookie生效的路径前缀,默认为“/”
domain cookie生效的站点,默认只能由设置它的站点读取,默认为None
secure HTTPS传输, 默认为False
在使用cookie时候一般不需要自己制定这些参数,除非是用途特殊用途,没有设置过期时间的cookie是回话cookie,在浏览器关闭的时候就失效了。
2.session功能
session使用时,MIDDLEWARE_CLASSES: django.contrib.sessions.middleware.SessionMiddleware
INSTALLED_APPS:
django.contrib.sessions
只要session激活后, 每个view中的request参数都有几个session属性。
是一个字典型的对象。session中尽量少用下划线开头的
存:
request.session["lover"]="baby"
取:
print request.session["lover"]
settiongs.py中常用的sission配置如下:
SESSION_EXPIRE_AT_BROWSER_CLOSE=True
SESSION_COOKIE_AGE=1209600 #session的cookie的生效时间,仅仅在SESSION_EXPIRE_AT_BROWSER_CLOSE为False时有效
SESSION_COOKIE_NAME="wolover" #session的cookie变量名
SESSION_COOKIE_DOMAIN=None #session的cookie_生效的域名
SESSION_COOKIE_SECURE=True #仅仅通过HTTPS传输session相关的COOKIE
3.自带的认证系统
user=request.user
if user.is_authenticated()
user.authenticate() 登录
user.login() 退出
常用的user属性:
user.username
user.email
user.password
user.is_active
常用的user方法:
user.is_authenticated()
user.is_anonymous()
user.get_full_name()
user.set_passwd()
4. 认证的form表单通常如下:(next变量会被login函数自动传进去,不需要自己传,如果忘记了用next会导致登录后自动重定向到next功能失效。)
<form action="/login/?next={{ next }}" method="post" autocomplete="off" class="login-form">
{% csrf_token %}
<div class="text-box">
<input type="text" name="username" class="login-name"/>
<input type="password" name="password" class="login-password"/>
</div>
<div class="login-tip">{{ request.login_message }}</div>
<input class="login-submit button" type="submit" value="登 录"/>
</form>
5. 常用login_required装饰器时要带上login_ulr="~~"参数。
6.login 的配置;
settings.py中加入:
LOGIN_URL="/login/" #指定登录的URLurls.py中加入:
LOGIN_REDIRECT_URL = "/"
url(r"^login/$",login,{"template_name":"login.html"}),login.html如下:
url(r"^logout/$",logout,{"next_page":"/login/"}),
或者 在action后,加入 {{ next }} 。
十一:django json序列化对象
在django中json用于序列化对象,把对象序列化之后可以永久存储。
JSON构建了两种结构:字典(又可以叫做对象、哈希表)、列表。
这种数据格式在同样基于这些结构的编程语言之间交换成为了可能。
简单类型通过JSONencode编码之后和气原始的str()输出结果非常相似,但是有些类型发生了改变。
具体如下:
Python To Json:
python json
dict object
list,tuple array
str,unicode string
int,long,float number
True true
False false
None null
Json To Python:
object dict
array list
string unicode
int int,long
real float
true True
false False
null None
例如:
#coding:gbk
import json
a="工厂网"
a_json=json.dumps(a,encoding="gbk")
a_python=json.loads(a_json)
ensure_ascii参数作用: 如果ensureascii为True的时候,返回的字符串一般是str类型
如果为False, 返回的字符串是Unicode类型。
JSON loads时,总是把一切字符串转化为unicode字符串,其编码默认为utf8。可以自己制定编码
如下:
#coding:utf8
import json
a_json=json.dumps(a)
a_python=json.loads(a_json)
dumps的可选参数:
json.dumps(data,indent=4,separators=(‘,‘,":")) indent用于缩进,这样看起来美观,但是其增大了数据量,separators用于制定压缩项。
自定义类JSON序列化和反序列化:
#coding:utf8
import json
class test:
def __init__(self,name,age):
self.name=name
self.age=age
_u=test("zhou",22)
print type(_u),_u.__class__.__name__,_u.__module__
def object_to_dict(obj):
d={}
d["__class__"]=obj.__class__.__name__
d["__module__"]=obj.__module__
d.update(obj.__dict__)
return d
def dict_to_object(obj):
print obj
module_=__import__(obj["__module__"])
class_=getattr(module_,obj["__class__"])
buff=[]
for i in obj:
if "__" in i:
buff.append(i)
for i in buff:
obj.pop(i)
args={}
for i in obj:
args[str(i)]=obj[i]
return test(**obj)
_u_dict=object_to_dict(_u)
a=json.dumps(_u_dict)
b=json.loads(a)
c=dict_to_object(b)
print c.name,c.age
十二:memcache随记
easy_install ‘python-memcached‘即可安装
使用:
import memcache
conn=memcache.Client(["192.138.8.137:11211"],debug=0)
conn.set("a",1)
conn.get("a")
conn.set_multi({"k1":1,"k2":2},key_prefix="test")
conn.get_multi(["k1","k2"],key_prefix="test")
conn.delect("k1")
十三: redis随记
easy_install ‘redis‘
或者pip install redis
pip uninstall redis
redis中2.10的版本比较好用,没什么大的问题。 低版本可能有问题。
redis中有四种数据类型
key,value list set(集合) zset(有序集合,多了一个顺序属性)
使用:
import redis
conn=redis.Redis(host="192.168.8.137",port=6379,db=1) #进入1数据库
conn.set("a",1)
conn.set("b",2)
conn.dbsize() #1数据库的大小 2
conn.select(2)
conn.dbsize() # 2数据库的大小 0
conn.select(1)
conn.move("a",2) #移动键"a"的信息到数据库2,数据库1的键"a"消失
conn.select(2)
conn.get("a")
conn.save() #强行把数据库保存草硬盘。 保存时会堵塞。
conn.flushdb() 删除当前数据库中的所有数据
conn.exists("a") #看当前数据库中是否存在这个键值
conn.keys() 列出所有键的名字。 返回一个列表
例如:可能返回[‘a‘,‘b‘]
conn.set("a",1) 同 conn["a"]=1
conn.get("b") 同 conn["a"]
conn.delete("c")同 del conn["c"]
conn.getset("a",123) 返回老的数据,并塞入新的数据
conn.rename("c","_c") 键值改名
r.mset({"a":123,"b":456})
r.mget(["a","b"])######## [123,456]
#------------------------------------------------------------------------------
r.push("g","a") [a]
r.push("g","b") [b,a]
r.llen("g") #返回长度,相当于列表长度
r.lrange("g",start=0,end=-1) #返回在此范围内的元素,相当于列表切片
r.ltrim("g",start=0,end=100) #对此序列进行修剪,相当于列表中的a=a[0:101]
r.lrem("g","a",count=0) #从序列中删除所有等于"a"的元素
#-------------------------------------------------------------------------------
r.sadd("s","a") #向集合中添加元素
r.scard("s") #判断一个集合长度
r.sismember("s","a")#判断集合中"a"是否存在
r.srem("s","a") 从集合中删除此元素
r.sinter("s1","s2") #两个集合的交集
http://stackoverflow.com/questions/1780003/import-error-on-boost-python-hello-program
十四:重定向
django中302临时重定向:
from django.http import HttpResponseRedirect
return HttpResponseRedirect("http://www.baidu.com")
301永久重定向:
from django.http import HttpResponsePermanentRedirect("http://www.baidu.com")
十五:django工程的组织。
a. 可以这样组织, 新建一个工程mysite 会自动具有一个app mysite. 可以再新建一个文件夹。
且其和mysite在相同目录下, 然后再seting中加入这个新的app,例如yousite
b. 也可以这样足足,新建一个工程Mysite,然后其自动具有一个app mysite,再在mysite这个文件夹下新建一个目录,加入叫做yousite, 然后再settings中加入这个新的app,例如mysite.yousite。
这两种方法各有利弊, 目前来说对于不是超大型的工程,建议采用第二种方式。只有在预估自己的代码量超大的时候才用第一种方式。 因为少量的代码采用第一种方式会使得整个架子太大,太空。
还有对于,django中app的理解, django中一个app可以算作为一个小的独立功能,比如 主机监控和数据库监控。 按照标准每个app中都应该具有views.py models.py __init__.py 。然后把整个app加入settings.py中django就会为这个应用添加数据库映射 templatefinder等相关信息。不要忘记添加app。
在nginx和django配合使用的时候, 前端部分用到 js httprequest对象尽量用post方式,get方式有问题.
十六: Django安全系统
csrf: django内部带有csrf中间件,且 ‘django.middleware.csrf.CsrfViewMiddleware‘,一般是默认开启的中间件,
每一次在模板中使用时, 如果是post方式, 一般在模板中加一个 {% csrf_token %}的标签, 如果是用ajax的方式并且也是用post方式的话, 需要加一个
X_CSRFTOKEN的header.其值是cookie中的csrftoken的值。
csrf是跨站点请求伪造, django对于csrf的防止是通过 cookie的 csrftoken+post中取到的csrftoken的值进行对比,如果相同的话,那么这是一个正常用户,如果不同,那么就
很可能是csrf跨站请求。 所以, get请求一般对于查询时使用,post对于写入时使用。
sql注入: 一般常见于通过get形式进行查询时,没有对get的参数进行有效的转义,信任了各户端, 导致可能会使客户端获取到不该获取的信息甚至是删除了你的数据库。
解决方案就是: 查询的sql游标最好只给读的权限,同时对用户输入的参数进行有效的转义和筛选。绝不信任用户提交的数据!
XSS跨站脚本: 举个例子:如果一个用户在自己的简历中假如了一段不被信任的JS脚本, 其他用户在查看其简历的时候就会自动运行这些脚本, 这是我们不愿意看到的!
解决方案就是: 总是对从数据库中取出的数据进行转义, 除非你有其他特别的用途!!!
十七:django json的使用
************************************
json=simplejson.dumps(buff,ensure_ascii=False) #ensure_ascii为了保证中文不乱码的问题
return HttpResponse(json,mimetype="application/javascript")
十八。django中引入第三方认证:
settings.py中加入:
AUTHENTICATION_BACKENDS=("django.contrib.auth.backends.ModelBackend",
"digger.auth.SelfBackend")
__author__ = ‘python‘
from django.contrib.auth.models import User,check_password
import MySQLdb
def get_mysql_conn():
conn=MySQLdb.connect(host="192.168.1.101",port=3306,user="zhou",passwd="13523136191",charset="utf8")
return conn
class SelfBackend(object):
def authenticate(self,username=None,password=None):
if username=="zhou" and password=="123456":
try:
user=User.objects.get(username=username)
except User.DoesNotExist:
user=User(username=username,password="get from self")
user.is_staff=True #具有进入admin的权限
user.is_superuser=True #具有进入admin并且能够更改设置的权限,超级管理员,和初级的admin 一样
user.is_active=True#账号处于激活状态
user.save()
return user
else:
conn=get_mysql_conn()
sqlstring="select * from test.auth WHERE user=‘%s‘ AND passwd=‘%s‘"%(username,password)
cursor=conn.cursor()
cursor.execute(sqlstring)
result=cursor.fetchall()
if result!=None:
try:
user=User.objects.get(username=username)
except User.DoesNotExist:
user=User(username=username,password=password)
user.is_active=True
user.is_staff=True
user.is_active=True
user.save()
return user
else:
return None
def get_user(self,user_id):
try:
return User.objects.get(pk=user_id)
except User.DoesNotExist:
return None
19. setting.py中Debug设置
在正式发布的时候Debug一般要设置为False, 但是在设置完False之后,很可能会出现500的问题, 此时只需要设置成如下即可!
ALLOWED_HOSTS = [‘*‘]
20. django中直接操作SQL:
1. 可以直接用MySQLdb进行处理, conn=connect() conn.cursor. execute(sqlstring,***)
2. conn=connections["default"] cursor=conn.cursor() conn.cursor.execute (sqlstring, ***)
sqlstring的写法:
(“select from_unixtime(begintime,‘%%Y%%m%%d‘) as begitdate ,count(*) as countnum from datamining.digger_djt_middle ”)
*** 的写法:
()
为了保持兼容性, 就算是没有参数,args也要写上一个空的元组。
如果有参数 那就直接用%s进行替代即可。常用的如下:
cursor.execute("selcet * from test",())
cursor.execute("select from_unixtime(begintime,‘%%Y%%m%%d‘) as begitdate ,count(*) as countnum from datamining.digger_djt_middle where id = %s ",(3,))
21. django中 routers配置
DATABASE_ROUTERS=[‘myblog.routers.Router‘] #Database router 配置
然后再规定位置写好这个Router。 其中model._meat.app_label 为models文件所在的包名。若在myblog下面有models.py那么如果用models.py里面的内容orm时就会其model的app_label就是 myblog
class Router(object):
def db_for_read(self, model, **hints):
print locals()
print model._meta.app_label
return ‘default‘
def db_for_write(self, model, **hints):
print locals()
return ‘default‘
22.django中小于
aaa__lt aaa__gt大于 lte小于等于 gte大于等于
23.对于cookie中的中文需要unquote才能得到中文。
23。django中时区的设置。
时区设置为,上海。 然后 use_tz设置为False, 如果设置为True, 其会影响 datetimefield的结果。
以上是关于Django基础笔记的主要内容,如果未能解决你的问题,请参考以下文章