上一篇做了基础工作,完成了django与django-cms的安装与配置,繁琐的是它们那些依赖也要一项一项的去了解,不会有一键安装这种好事。今天这一篇将创建我的第一个APP。他是一个简单的产品管理与展示系统。let’s go!
模型
python manage.py startapp products
在已有的Project中使用这个命令可以自动创建一个默认的APP(一个python模块)。他包括四个默认文件。我的APP需要数据库支持,所以首先要在models.py中设计数据库结构。django提供了非常方便的数据库对象化方案。具体的类如下:
import os
from datetime import date
from django.db import models
from filebrowser.fields import FileBrowseField
# 每个类代表一张表,类的属性指代表的字段
class Categroy(models.Model):
# name用于后台显示,title用于前端页面显示
name = models.CharField(max_length = 100)
title = models.CharField(max_length = 100)
order = models.IntegerField(default = 0)
# 用户可以自定义路径,及此分类下的模板
path = models.CharField(max_length = 20, blank=False)
list_template = models.CharField(max_length = 200, blank = False, default = "products/list.html")
item_template = models.CharField(max_length = 200, blank = False, default = "products/item.html")
keywords = models.CharField(max_length = 300, blank = False)
descoription = models.TextField(blank = False)
display = models.BooleanField(default = True)
add_time = models.DateTimeField(auto_now_add = True)
# 支持无限分类, 注意与自己做一对一关系时,第一个参数使用字符型的self,不能直接用变量,因为它指代的是实例
parent = models.ForeignKey('self', blank = True, null = True)
# 使用一个递归来计算当前分类的层级
def _count_level(self):
def loop_count_level(parent, level = 2):
if parent.parent:
return loop_count_level(parent.parent, level + 1)
else:
return level
if self.parent == None:
return 1
else:
return loop_count_level(self.parent)
# 可以自定义一些方法做一些计算,同时用property把它变成实例的属性
level = property(_count_level)
def _children(self):
# 使用 ‘__’ 双下划线可以指代关联表中的字段
return Categroy.objects.filter(parent__id = self.id)
children = property(_children)
def _products(self):
return Product.objects.filter(categroy = self)
products = property(_products)
def _all_products(self):
cates = [self] + [c for c in self.children]
# 使用 ‘__’ 双下划线还可以做一些简单的字段查询
return Product.objects.filter(categroy__in = cates)
all_products = property(_all_products)
# 在没有明确指明时,实例可以返回的字符串信息
def __unicode__(self):
return "%s %s" % ("-" * self.level, self.name)
class Product(models.Model):
....
安装APP
创建完表字段后,我们有两步要做,一是把APP安装到django中:
INSTALLED_APPS = (
...
'products',
...
)
二是要使用命令在数据库中生成真正的表:
python manage.py syncdb --all
在admin中管理
django的admin后台为程序员节省了很多时间,它可以快速为你自己的APP搭建一个后台。我们需要在APP中创建一个admin.py文件,在其中把我们的数据模型注册到admin中,代码如下:
from django.contrib import admin
from news.models import Categroy, Products
admin.site.register(Categroy)
admin.site.register(Products)
再次登录后台会发现已经可以看到Categroy和Products的管理条目了,基本的删查改都提供。这时还有个问题,文本编辑器(tinyMCE)没有出现,接下来要对admin.py做一些定制工作:
# 继承ModelForm类可以控制admin后台中编辑form中的项
class ProductForm(forms.ModelForm):
content = forms.CharField(widget=TinyMCE(attrs={'cols': '90', 'rows': '60'}))
class Meta:
model = Product
class ProductAdmin(admin.ModelAdmin):
form = ProductForm
admin.site.register(Categroy)
admin.site.register(Product, ProductAdmin)
相当于覆盖了默认的表单内容。django还提供了很多功能让用户可以方便的定制后台。
页面展示
页面展示需要考虑两个问题:通过什么样的URL访问;如何展示内容。django通过 urls.py 来设置访问的url,views.py 则包括所有的视图代码。
其实我们project创建时已经有了一个urls.py,把需要访问的url都设置在此处也没有问题,但为了减少耦合,尽量把app自己的url规则配置在自己的urls.py中。只需要在project中的urls.py中设置如下代码,即可把访问串联起来:
url(r'^products/', include("product.urls")) # 注意正则中并没有出现"$"结束符
每一个url正则对应一个view, 可以多个url正则对应一个view。没有命名的正则表达式组,按顺序对应view的参数,而命名的正则表达式组对应view参数的名称。
(r'^(?P<id>[0-9]+)/?$', views.product) # product方法中的参数id 可以获取url中匹配到的id
views中用作返回视图的方法,总能接收一个’request’参数,而它本身必须返回一个 HttpResponse对象
def product(request, id=""):
try:
id = int(id)
product = Product.objects.get(id = id)
except Product.DoesNotExist:
return Http404
# render_to_response能快速的返回HttpResponse对象
return render_to_response(product.categroy.item_template,
{"product":product}, context_instance=RequestContext(request))
# context_instance 上下文实例可以让你在模板中访问一些常规的变量,
# 比如,当前用户这样的信息,不需要你自己往 dictionary 加入这些内容。
模板
模板的内容相对简单,前端对这些比较熟悉。