存档: 标签: ‘Django’

django 数据库查询常用符号

没有评论 2012年1月5日

__exact        精确等于 like ‘aaa’
__iexact    精确等于 忽略大小写 ilike ‘aaa’
__contains    包含 like ‘%aaa%’
__icontains    包含 忽略大小写 ilike ‘%aaa%’,但是对于sqlite来说,contains的作用效果等同于icontains。
__gt    大于
__gte    大于等于
__lt    小于
__lte    小于等于
__in     存在于一个list范围内
__startswith   以…开头
__istartswith   以…开头 忽略大小写
__endswith     以…结尾
__iendswith    以…结尾,忽略大小写
__range    在…范围内
__year       日期字段的年份
__month    日期字段的月份
__day        日期字段的日
__isnull=True/False
__isnull=True 与 __exact=None的区别

Django中的常用命令

没有评论 2011年12月6日

django 基本命令操作:
django-admin startproject jay:建立一个jay的项目
django-admin startapp haha 建立一个haha的APP
python manage.py runserver 启动服务器
python manage.py validate 检查模型的有效性
python manage.py sqlall app名称
python manage.py syncdb:同步数据库,这也大大减少了不懂的数据库知识的开发人员的工作量
python manage.py sql <appname>:查看数据库中所存在的表
python manage.py shell:进入SHELL状态

settings.py:设置数据库,环境语言,时区,中间件,安装APP,模板目录,国际化等等

urls.py:配置VIEW和URL的映射

Django中使用多线程发送邮件

1条评论 2011年6月25日
1、settings.py 增加Email设置

#mail
EMAIL_HOST = ‘smtp.gmail.com’                   #邮件smtp服务器
EMAIL_PORT = ’25′                                        #端口
EMAIL_HOST_USER = ‘code***@gmail.com’  #邮件账户
EMAIL_HOST_PASSWORD = ‘*********’      #密码
EMAIL_USE_TLS = False
2、views.py 发送邮件


from django.core.mail import EmailMultiAlternatives
from django.template import loader
from settings import EMAIL_HOST_USER
import threading
from_email = EMAIL_HOST_USER
class EmailThread(threading.Thread):
def __init__(self, subject, body, from_email, recipient_list, fail_silently, html):
self.subject = subject
self.body = body
self.recipient_list = recipient_list
self.from_email = from_email
self.fail_silently = fail_silently
self.html = html
threading.Thread.__init__(self)
def run (self):
msg = EmailMultiAlternatives(self.subject, self.body, self.from_email, self.recipient_list)
if self.html:
msg.attach_alternative(self.body,self.html)
msg.send(self.fail_silently)
def send_mail(subject, body, from_email, recipient_list, fail_silently=False, html=None, *args, **kwargs):
EmailThread(subject, body, from_email, recipient_list, fail_silently, html).start()
def test_mail(request):
subject = u'邮件主题'
to_mail_list = ['abc@gmail.com','test@qq.com']
body = loader.render_to_string('mail_template.html',
{'email':email,'date':datetime.today(), }
)
send_mail(subject,body,from_email,to_mail_list,html="text/html")
return "ok"
代码比较简单就不解释了,到这里Django多线程发送Email基本功能已经完成。当然了还需要新建一个模板文件,这里是以mail_template.html命名的。

Django 中 ManyToMany 的关联方法

没有评论 2011年4月4日

什么是 ManyToMany?

举个简单的例子,一本书可以有一个或多个作者,而一个作者可以写多本书,那么对于书和作者来说,他们的关系就不是一一对应的,而是多对多(也就是 ManyToMany)。在 Django 的 model 中,有个 ManyToManyField 专门来处理这种关系。

我写了个小应用来的管理 blog 的文章,因此我设计了这样的 model:

class Tag(models.Model):
    name = models.CharField(max_length=30)

class Entry(models.Model):
    title = models.CharField(max_length=100)
    pub_date = models.DateField(blank=True, null=True)
    content = models.TextField()
    tags = models.ManyToManyField(Tag)

Entry 和 Tag 分别代表了 blog 的两大组件——文章和分类。Tag 很简单,只用一个 name 字段来存放 tag 的名字。而 Entry 则用了 title, pub_date, content 这 3 个字段来存放文章的标题、发布时间和文章内容。那么 tags = models.ManyToManyField(Tag) 是干什么的?

和之前的例子一样,一篇文章会有好几个 tag,而 tag 也下辖很多篇文章。从 Entry 的角度看,它有很多 tag(s),于是通过 ManyToManyField 与 Tag 关联起来。打开数据库,你可以看到 Django 专门生成了名为 entry_tags 的表来保存文章与 tag 的对应关系。

model 是搞定了,但实际中如何使用 model 往数据库里添加文章和 tag? 可以用 Model 的 save 方法或者 Manager 提供的 create 方法向数据库写入数据,因此可以这样添加 tag:

t = Tag()
t.name = '测试'
t.save()

# 或者
Tag.objects.create(name='测试')

文章也是一样:

e = Entry()
e.title =  '测试'
e.pub_date = '2010-03-11'
e.content = 'test'
e.save()

但这样只能分别添加 tag 和文章,而且文章与 tag 的对应关系没有添加进去。要想在添加文章的时候顺便把 tag 和对应关系也一并存放,我们需要重载 save 方法:

class Entry(models.Model):
    title = models.CharField(max_length=100)
    pub_date = models.DateField(blank=True, null=True)
    content = models.TextField()
    tags = models.ManyToManyField(Tag)
    taglist = []

    def save(self, *args, **kwargs):
        super(Entry, self).save()
        for i in self.taglist:
            p, created = Tag.objects.get_or_create(name=i)
            self.tags.add(p)

在 Entry 的属性里多了个 taglist,它用来储存文章的 tag。之后使用 save 的时候,会先调用 Entry 父类的 save 方法将 title, pub_date, content 写入 entry 表,然后取出 taglist 中的每一个 tag,调用 Tag.objects.get_or_create 方法获得 Tag 对象,再用 ManyToMany 的 add 方法添加 Tag 对象,最后二次调用 save 方法把数据真正存入数据库

Manager 的 get_or_create 方法接受给定参数作为查询条件,如果找到结果就返回找到的对象,如果没找到就先创建对象再返回它,这样一来我们就不用担心会出现重复添加 tag 的问题了。

能否在添加的文章的时候也使用 get_or_create 方法来防止重复添加呢,答案是当然可以。自定义一个 Manager 重载 get_or_create 即可。

class EntryManager(models.Manager):
    def get_or_create(self, **kwargs):
        defaults = kwargs.pop('defaults', {})
        taglist = defaults.pop('taglist', {})
        Entry.taglist = taglist
        kwargs.update(defaults)
        super(EntryManager, self).get_or_create(**kwargs)

class Entry(models.Model):
    title = models.CharField(max_length=100)
    pub_date = models.DateField(blank=True, null=True)
    content = models.TextField()
    tags = models.ManyToManyField(Tag)
    taglist = []
    objects = EntryManager()

    def save(self, *args, **kwargs):
        super(Entry, self).save()
        for i in self.taglist:
            p, created = Tag.objects.get_or_create(name=i)
            self.tags.add(p)
        self.taglist = []

因为 get_or_create 实际上还是会最终调用 model (Entry) 的 save 方法,所以才会用Entry.taglist = taglist 在真正执行 get_or_create 之前先把 tag 放进去。

最后就可以这样储存文章:

title = '测试'
data = {'taglist': tags,
        'pub_date': date,
        'content': output,
       }
Entry.objects.get_or_create(title=title, defaults=data)

以上代码均来自 Antidote(https://github.com/Vayn/Antidote),这是一个为方便用 jekyll 写 blog 的人管理文章的应用,欢迎 clone。

 

Django日期的表示方法

1条评论 2011年4月1日

因为开发中经常用到日期的表示方法,而自己又记不住。没办法,好记性不如烂笔头。把他记下来,以后用的时候直接看:

 

%a 星期几的简写
%A 星期几的全称
%b 月分的简写
%B 月份的全称
%c 标准的日期的时间串
%C 年份的后两位数字
%d 十进制表示的每月的第几天
%D 月/天/年
%e 在两字符域中,十进制表示的每月的第几天
%F 年-月-日
%g 年份的后两位数字,使用基于周的年
%G 年分,使用基于周的年
%h 简写的月份名
%H 24小时制的小时
%I 12小时制的小时
%j 十进制表示的每年的第几天
%m 十进制表示的月份
%M 十时制表示的分钟数
%n 新行符
%p 本地的AM或PM的等价显示
%r 12小时的时间
%R 显示小时和分钟:hh:mm
%S 十进制的秒数
%t 水平制表符
%T 显示时分秒:hh:mm:ss
%u 每周的第几天,星期一为第一天 (值从0到6,星期一为0)
%U 第年的第几周,把星期日做为第一天(值从0到53)
%V 每年的第几周,使用基于周的年
%w 十进制表示的星期几(值从0到6,星期天为0)
%W 每年的第几周,把星期一做为第一天(值从0到53)
%x 标准的日期串
%X 标准的时间串
%y 不带世纪的十进制年份(值从0到99)
%Y 带世纪部分的十制年份
%z,%Z 时区名称,如果不能得到时区名称则返回空字符。
%% 百分号

Django数据库模型的字段类型总结

没有评论 2011年3月28日

从网上找了好长时间,总算是找了个差不多。因为经常用,自己又记不住,所以还是总结一下。帮助自己的同时也能帮助别人:

V=models.CharField(max_length=None[, **options])    #varchar

V=models.EmailField([max_length=75, **options])    #varchar
V=models.URLField([verify_exists=True, max_length=200, **options])    #varchar
V=models.FileField(upload_to=None[, max_length=100, **options])    #varchar
#upload_to指定保存目录可带格式,
V=models.ImageField(upload_to=None[, height_field=None, width_field=None, max_length=100, **options])
V=models.IPAddressField([**options])    #varchar
V=models.FilePathField(path=None[, match=None, recursive=False, max_length=100, **options]) #varchar
V=models.SlugField([max_length=50, **options])    #varchar,标签,内含索引
V=models.CommaSeparatedIntegerField(max_length=None[, **options])    #varchar

V=models.IntegerField([**options])    #int
V=models.PositiveIntegerField([**options])    #int 正整数
V=models.SmallIntegerField([**options])    #smallint
V=models.PositiveSmallIntegerField([**options])    #smallint 正整数
V=models.AutoField(**options)    #int;在Django代码内是自增
V=models.DecimalField(max_digits=None, decimal_places=None[, **options])    #decimal
V=models.FloatField([**options])    #real

V=models.BooleanField(**options)    #boolean或bit

V=models.NullBooleanField([**options])    #bit字段上可以设置上null值

V=models.DateField([auto_now=False, auto_now_add=False, **options])    #date
#auto_now最后修改记录的日期;auto_now_add添加记录的日期
V=models.DateTimeField([auto_now=False, auto_now_add=False, **options])    #datetime
V=models.TimeField([auto_now=False, auto_now_add=False, **options])    #time

V=models.TextField([**options])    #text
V=models.XMLField(schema_path=None[, **options])    #text

——————————————————————————–
V=models.ForeignKey(othermodel[, **options])    #外键,关联其它模型,创建关联索引
V=models.ManyToManyField(othermodel[, **options])    #多对多,关联其它模型,创建关联表
V=models.OneToOneField(othermodel[, parent_link=False, **options])    #一对一,字段关联表属性

 

关于Django模板不能运算的临时解决办法

1条评论 2011年3月25日

今天用django模板显示数据的时候,想根据数据库内id号取模来实现显示不同的CSS类。结果测试了一天也没运算成功。后来查了大量官方文档才知道,模板是不支持数学运算的(真是个让人绝望的缺陷)。没办法,网站还是要做下去的。只能想想别的办法。

功夫不负苦心人,在用了N多个关键词google了之后。终于找到一条能实现基本功能的替代方法就是:

用django的divisibleby标签实现,如下:

{% for each in somelist %}

{% if forloop.counter0|divisibleby:2 %}

<div class=”class1″></div>

{% else %}

<div class=”class2″></div>

{% endif %}

{% endfor %}

divisibleby标签的意义是用后面的参数去除,除尽为True,否则为False