为大漫使用django进行开发已经有几个月了,总算没白白浪费时间,经过断断续续的开发,终于发布了内部1.0的版本,可以在线看漫画。
现在总结一下其中关于django的实践,里面提到的技术点很片面不是很全,但对于大漫的项目来说是刚刚好。如果觉得哪里不是很清楚请自行google找资料学习,这里也没有对django的基础进行说明。有问题可以给我留言
1)添加模块
url.py中配置/comic下的请求都转到comic模块进行处理。
需要在comic模块中添加一个url.py文件,添加如下语句到项目的url.py中
(r'^comic/', include('bigcomic.comic.urls')),
2)在django中对静态文件的配置
(r'^media/(?P.*)$', 'django.views.static.serve',
{'document_root': settings.STATIC_PATH}),
(r'^comicviewer/(?P.*)$', 'django.views.static.serve',
{'document_root': settings.FLEX_PATH}),
在settings中添加相应的路径配置,如下
BIGCOMIC_ROOT = os.path.dirname(__file__)
STATIC_PATH = os.path.join(BIGCOMIC_ROOT, 'media')
FLEX_PATH = os.path.join(BIGCOMIC_ROOT, 'comicviewer')
3)乱码问题
在django的settings.py文件中添加
DEFAULT_CHARSET = 'utf8'
py文件中要在文件第一行加入如下内容
#-*-coding:utf-8-*-
数据库编码要设置成utf-8
4)看下model的配置
首先model要继承models.Model
class Book(models.Model):
大漫所用到的字段类型
enname = models.CharField(unique=True,max_length=100,null=True,blank=True)
字符串类型,数据是唯一的,最大长度为100,可以为null,前台form不验证
category_id = models.IntegerField(default=1)
数字类型,默认值为1
createTime = models.DateTimeField(auto_now_add=True)
时间类型,第一次创建为当前时间,之后不会变动
updateTime = models.DateTimeField(auto_now=True)
时间类型,自动添加时间,第一次为当前时间,每次数据有变动都会更新
comicInfo = models.TextField(null=True,blank=True)
数据库text类型,可以为null,前台form表单不验证
comic = models.ForeignKey(Book)
多对一,一对多的关联。如果book模型没有定义,则使用"Book"的字符串来代替
acg = models.OneToOneField(Acg,primary_key=True)
一对一关联,并设置这个id为主键,防止主键变成自增长
5)meta中对model的排序,以及表名的映射
class Meta:
ordering = ['-browseCount','-updateTime']
class Meta:
ordering = ['-updateTime']
在一个model类中编写class meta则定义具体的排序规则,"-"为倒叙排列
6)关于json
django中内置了simplejson的组件,按如下引用
from django.utils import simplejson
使用方法为:return HttpResponse(simplejson.dumps(data))
但simplejson有个问题就是只支持基本的数据类型,对与自定义的model类型他并不能按照我们想要的
格式进行转换,所以需要我们单独进行扩展。参考了官方网站的方法但觉得很不好用,所以只好自己在
定义的model中加入json方法,来解决这个问题,使用如下
def json(self):
在model类中自定义一个json的方法,此方法返回由类变量组装成的一个字典。
在产生json格式的时候通过对象的json方法来获得这个对象的转换方式,如下
[book.json() for book in hotList]
7)取得10条数据并按要求排序
hotList = Book.objects.order_by('-browseCount')[:10]
8)接受request的数据
从post中取得数据,如果不存在则默认值为1
pageNumber = request.POST.get('pageNumber',1)
从get中取得数据,如果不存在则默认值为1
pageNumber = request.GET.get('pageNumber',1)
从所有请求中取得数据,如果不存在则默认值为1
pageNumber = request.REQUEST.get('pageNumber',1)
判断一个请求是post还是get方式
if request.method == 'GET':
对于request的操作可以参考
http://www.woodpecker.org.cn/obp/django/django-faq/request_response.html
9)分页功能
首先从request中得到页号pageNumber,然后取得要分页的数据,这里的数据是取得所有数据
book_list = Book.objects.all()
使用分页对象对数据进行分页,设置每页的页大小
paginator = Paginator(book_list,settings.BIGCOMIC_PAGESIZE)
然后传入取得的页号,来取出这页的数据
contacts = paginator.page(pageNumber)
如果没有数据会出现EmptyPage异常,所以这里需要捕获这个异常并进行处理
10)模板中的分页功能使用
首先是后台view中对数据进行分页,然后将分页所得的数据传到模板中,通过模板进行数据页号,上一页下一页的显示
return render_to_response('comic/list.html',{'contacts':contacts})
模板中代码如下
{% if contacts.has_previous %}
previous
{% endif %}
{% for p in contacts.paginator.page_range %}
{{p}}
{% endfor %}
共有{{ contacts.paginator.num_pages }}页
{% if contacts.has_next %}
next
{% endif %}
11)进行条件搜索
使用Q对象可以进行搜索条件的组装
q = Q(acg__name__icontains=searchContent) | Q(author__icontains=searchContent) |Q (keyword__icontains=searchContent)
对comic_book表的author字段和keyword字段以及与其有一对一关联的acg表的name字段进行ilike查找,这里ilike与like的区别为不区分大小写,3相之间为“或”的关系
book_list = Book.objects.filter(q)
根据组装的语句在数据中进行查找,这里如果没有找到任何数据则会扔出ObjectDoesNotExist异常
12)对数据进行添加操作
先根据request中传进来的id取得一个数据库中的相应数据
book = Book.objects.get(pk=book_id)
这里如果数据不存在则扔出ObjectDoesNotExist异常
然后可以对这个数据对象进行改动,最后通过save方法进行数据保存
book.save()
13)读取指定目录的文件列表
有个功能会从指定目录读取所有图片的文件名列表并对这个列表中的文件名进行拼装成URL返回这个列表
imageUrl = [ viewurl + list for list in os.listdir(localdir)]
imageUrl.sort()
其中viewurl为域名,localdir为本地的一个目录,如/home/www
sort()为排序,python中的列表排序并不会返回任何东西
14)在url中传递参数
url.py中如下配置
(r'detail/(\d*)/page/(\d*)/$', 'bigcomic.comic.views.detail'),
则访问时,在请求的url中detail后跟一个漫画的ID,page后跟具体要请求的页号。例子如下
http://www.baidu.com/comic/detail/5/page/2
参数怎样传递到view的方法中呢,则view中的方法如下,在request后多加两个参数就可以获得url中的数据
def detail(request, comicID, pageNumber):
15)方法的事物控制
需要在settings.py中添加事物的中间件,如下
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.middleware.transaction.TransactionMiddleware',
)
然后在方法名上加入事物的配置
@transaction.commit_on_success
def create(request):
这里顺带说一下CommonMiddleware这个中间件的功能是帮你补全url中的/,使得你在输入url的时候不用去补最后的/
16)模板目录的配置
在settings.py中对模板目录进行如下配置
TEMPLATE_DIRS = (
os.path.join(BIGCOMIC_ROOT,'templates'),)
现在总结一下其中关于django的实践,里面提到的技术点很片面不是很全,但对于大漫的项目来说是刚刚好。如果觉得哪里不是很清楚请自行google找资料学习,这里也没有对django的基础进行说明。有问题可以给我留言
1)添加模块
url.py中配置/comic下的请求都转到comic模块进行处理。
需要在comic模块中添加一个url.py文件,添加如下语句到项目的url.py中
(r'^comic/', include('bigcomic.comic.urls')),
2)在django中对静态文件的配置
(r'^media/(?P.*)$', 'django.views.static.serve',
{'document_root': settings.STATIC_PATH}),
(r'^comicviewer/(?P.*)$', 'django.views.static.serve',
{'document_root': settings.FLEX_PATH}),
在settings中添加相应的路径配置,如下
BIGCOMIC_ROOT = os.path.dirname(__file__)
STATIC_PATH = os.path.join(BIGCOMIC_ROOT, 'media')
FLEX_PATH = os.path.join(BIGCOMIC_ROOT, 'comicviewer')
3)乱码问题
在django的settings.py文件中添加
DEFAULT_CHARSET = 'utf8'
py文件中要在文件第一行加入如下内容
#-*-coding:utf-8-*-
数据库编码要设置成utf-8
4)看下model的配置
首先model要继承models.Model
class Book(models.Model):
大漫所用到的字段类型
enname = models.CharField(unique=True,max_length=100,null=True,blank=True)
字符串类型,数据是唯一的,最大长度为100,可以为null,前台form不验证
category_id = models.IntegerField(default=1)
数字类型,默认值为1
createTime = models.DateTimeField(auto_now_add=True)
时间类型,第一次创建为当前时间,之后不会变动
updateTime = models.DateTimeField(auto_now=True)
时间类型,自动添加时间,第一次为当前时间,每次数据有变动都会更新
comicInfo = models.TextField(null=True,blank=True)
数据库text类型,可以为null,前台form表单不验证
comic = models.ForeignKey(Book)
多对一,一对多的关联。如果book模型没有定义,则使用"Book"的字符串来代替
acg = models.OneToOneField(Acg,primary_key=True)
一对一关联,并设置这个id为主键,防止主键变成自增长
5)meta中对model的排序,以及表名的映射
class Meta:
ordering = ['-browseCount','-updateTime']
class Meta:
ordering = ['-updateTime']
在一个model类中编写class meta则定义具体的排序规则,"-"为倒叙排列
6)关于json
django中内置了simplejson的组件,按如下引用
from django.utils import simplejson
使用方法为:return HttpResponse(simplejson.dumps(data))
但simplejson有个问题就是只支持基本的数据类型,对与自定义的model类型他并不能按照我们想要的
格式进行转换,所以需要我们单独进行扩展。参考了官方网站的方法但觉得很不好用,所以只好自己在
定义的model中加入json方法,来解决这个问题,使用如下
def json(self):
在model类中自定义一个json的方法,此方法返回由类变量组装成的一个字典。
在产生json格式的时候通过对象的json方法来获得这个对象的转换方式,如下
[book.json() for book in hotList]
7)取得10条数据并按要求排序
hotList = Book.objects.order_by('-browseCount')[:10]
8)接受request的数据
从post中取得数据,如果不存在则默认值为1
pageNumber = request.POST.get('pageNumber',1)
从get中取得数据,如果不存在则默认值为1
pageNumber = request.GET.get('pageNumber',1)
从所有请求中取得数据,如果不存在则默认值为1
pageNumber = request.REQUEST.get('pageNumber',1)
判断一个请求是post还是get方式
if request.method == 'GET':
对于request的操作可以参考
http://www.woodpecker.org.cn/obp/django/django-faq/request_response.html
9)分页功能
首先从request中得到页号pageNumber,然后取得要分页的数据,这里的数据是取得所有数据
book_list = Book.objects.all()
使用分页对象对数据进行分页,设置每页的页大小
paginator = Paginator(book_list,settings.BIGCOMIC_PAGESIZE)
然后传入取得的页号,来取出这页的数据
contacts = paginator.page(pageNumber)
如果没有数据会出现EmptyPage异常,所以这里需要捕获这个异常并进行处理
10)模板中的分页功能使用
首先是后台view中对数据进行分页,然后将分页所得的数据传到模板中,通过模板进行数据页号,上一页下一页的显示
return render_to_response('comic/list.html',{'contacts':contacts})
模板中代码如下
{% if contacts.has_previous %}
previous
{% endif %}
{% for p in contacts.paginator.page_range %}
{{p}}
{% endfor %}
共有{{ contacts.paginator.num_pages }}页
{% if contacts.has_next %}
next
{% endif %}
11)进行条件搜索
使用Q对象可以进行搜索条件的组装
q = Q(acg__name__icontains=searchContent) | Q(author__icontains=searchContent) |Q (keyword__icontains=searchContent)
对comic_book表的author字段和keyword字段以及与其有一对一关联的acg表的name字段进行ilike查找,这里ilike与like的区别为不区分大小写,3相之间为“或”的关系
book_list = Book.objects.filter(q)
根据组装的语句在数据中进行查找,这里如果没有找到任何数据则会扔出ObjectDoesNotExist异常
12)对数据进行添加操作
先根据request中传进来的id取得一个数据库中的相应数据
book = Book.objects.get(pk=book_id)
这里如果数据不存在则扔出ObjectDoesNotExist异常
然后可以对这个数据对象进行改动,最后通过save方法进行数据保存
book.save()
13)读取指定目录的文件列表
有个功能会从指定目录读取所有图片的文件名列表并对这个列表中的文件名进行拼装成URL返回这个列表
imageUrl = [ viewurl + list for list in os.listdir(localdir)]
imageUrl.sort()
其中viewurl为域名,localdir为本地的一个目录,如/home/www
sort()为排序,python中的列表排序并不会返回任何东西
14)在url中传递参数
url.py中如下配置
(r'detail/(\d*)/page/(\d*)/$', 'bigcomic.comic.views.detail'),
则访问时,在请求的url中detail后跟一个漫画的ID,page后跟具体要请求的页号。例子如下
http://www.baidu.com/comic/detail/5/page/2
参数怎样传递到view的方法中呢,则view中的方法如下,在request后多加两个参数就可以获得url中的数据
def detail(request, comicID, pageNumber):
15)方法的事物控制
需要在settings.py中添加事物的中间件,如下
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.middleware.transaction.TransactionMiddleware',
)
然后在方法名上加入事物的配置
@transaction.commit_on_success
def create(request):
这里顺带说一下CommonMiddleware这个中间件的功能是帮你补全url中的/,使得你在输入url的时候不用去补最后的/
16)模板目录的配置
在settings.py中对模板目录进行如下配置
TEMPLATE_DIRS = (
os.path.join(BIGCOMIC_ROOT,'templates'),)