Django续
Form
django中的Form一般有两种功能:
- 输入html
- 验证用户输入
#!/usr/bin/env python # -*- coding:utf-8 -*- import re from django import forms from django.core.exceptions import ValidationError def mobile_validate(value): mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$') if not mobile_re.match(value): raise ValidationError('手机号码格式错误') class PublishForm(forms.Form): user_type_choice = ( (0, u'普通用户'), (1, u'高级用户'), ) user_type = forms.IntegerField(widget=forms.widgets.Select(choices=user_type_choice, attrs={'class': "form-control"})) title = forms.CharField(max_length=20, min_length=5, error_messages={'required': u'标题不能为空', 'min_length': u'标题最少为5个字符', 'max_length': u'标题最多为20个字符'}, widget=forms.TextInput(attrs={'class': "form-control", 'placeholder': u'标题5-20个字符'})) memo = forms.CharField(required=False, max_length=256, widget=forms.widgets.Textarea(attrs={'class': "form-control no-radius", 'placeholder': u'详细描述', 'rows': 3})) phone = forms.CharField(validators=[mobile_validate, ], error_messages={'required': u'手机不能为空'}, widget=forms.TextInput(attrs={'class': "form-control", 'placeholder': u'手机号码'})) email = forms.EmailField(required=False, error_messages={'required': u'邮箱不能为空','invalid': u'邮箱格式错误'}, widget=forms.TextInput(attrs={'class': "form-control", 'placeholder': u'邮箱'}))
def publish(request): ret = {'status': False, 'data': '', 'error': '', 'summary': ''} if request.method == 'POST': request_form = PublishForm(request.POST) if request_form.is_valid(): request_dict = request_form.clean() print request_dict ret['status'] = True else: error_msg = request_form.errors.as_json() ret['error'] = json.loads(error_msg) return HttpResponse(json.dumps(ret))
扩展:ModelForm
在使用Model和Form时,都需要对字段进行定义并指定类型,通过ModelForm则可以省去From中字段的定义
class AdminModelForm(forms.ModelForm): class Meta: model = models.Admin #fields = '__all__' fields = ('username', 'email') widgets = { 'email' : forms.PasswordInput(attrs={'class':"alex"}), }
常用ORM操作:
from django.db import models class Blog(models.Model): name = models.CharField(max_length=100) tagline = models.TextField() def __str__(self): # __unicode__ on Python 2 return self.name class Author(models.Model): name = models.CharField(max_length=50) email = models.EmailField() def __str__(self): # __unicode__ on Python 2 return self.name class Entry(models.Model): blog = models.ForeignKey(Blog) headline = models.CharField(max_length=255) body_text = models.TextField() pub_date = models.DateField() mod_date = models.DateField() authors = models.ManyToManyField(Author) n_comments = models.IntegerField() n_pingbacks = models.IntegerField() rating = models.IntegerField() def __str__(self): # __unicode__ on Python 2 return self.headline
创建
>>> from blog.models import Blog >>> b = Blog(name='Beatles Blog', tagline='All the latest Beatles news.') >>> b.save()
这是在后台执行INSERT SQL操作。只有当Django执行了save()语句才会将执行的操作添加到数据库中。当然save()语句并没有返回值。
处理带外键关联或多对多关联的对象
外键的关联:
>>> from blog.models import Entry >>> entry = Entry.objects.get(pk=1) >>> cheese_blog = Blog.objects.get(name="Cheddar Talk") >>> entry.blog = cheese_blog >>> entry.save()
多对多关联:
>>> from blog.models import Author >>> joe = Author.objects.create(name="Joe") >>> entry.authors.add(joe)
添加多个多对多的对象
>>> john = Author.objects.create(name="John") >>> paul = Author.objects.create(name="Paul") >>> george = Author.objects.create(name="George") >>> ringo = Author.objects.create(name="Ringo") >>> entry.authors.add(john, paul, george, ringo)
查询
all_entries = Entry.objects.all() #查询所有 Entry.objects.filter(pub_date__year=2006) #查询所有pub_date为2006年的纪录 Entry.objects.all().filter(pub_date__year=2006) #与上面那句一样 >>> Entry.objects.filter( #链式查询 ... headline__startswith='What' ... ).exclude( ... pub_date__gte=datetime.date.today() ... ).filter( ... pub_date__gte=datetime(2005, 1, 30) ... ) one_entry = Entry.objects.get(pk=1) #单条查询 Entry.objects.all()[:5] #查询前5条 Entry.objects.all()[5:10] #你猜 Entry.objects.order_by('headline')[0] #按headline排序取第一条 Entry.objects.filter(pub_date__lte='2006-01-01') #相当于sql语句SELECT * FROM blog_entry WHERE pub_date <= '2006-01-01'; Entry.objects.get(headline__exact="Cat bites dog") #相当于SELECT ... WHERE headline = 'Cat bites dog'; Blog.objects.get(name__iexact="beatles blog") #与上面相同,只是大小写不敏感 Entry.objects.get(headline__contains='Lennon') #相当 于SELECT ... WHERE headline LIKE '%Lennon%';
#This example retrieves all Entry objects with a Blog whose name is 'Beatles Blog': Entry.objects.filter(blog__name='Beatles Blog') Blog.objects.filter(entry__headline__contains='Lennon')
Admin
django amdin是django提供的一个后台管理页面,给管理页面提供完善的html和css,使得你在通过Model创建完数据库表之后,就可以对数据进行增删改查,而使用django admin 则需要以下步骤:
- 创建后台管理员
- 配置url
- 注册和配置django admin后台管理页面
1、创建后台管理员
>> python manage.py createsuperuser
2、配置后台管理url
>> url(r'^admin/', include(admin.site.urls))
3、注册和配置django admin 后台管理页面
a、在admin中执行如下配置
from django.contrib import admin from app01 import models admin.site.register(models.UserType) admin.site.register(models.UserInfo) admin.site.register(models.UserGroup) admin.site.register(models.Asset)
b、设置数据表名称
class UserType(models.Model): name = models.CharField(max_length=50) class Meta: verbose_name = '用户类型' verbose_name_plural = '用户类型'
c、打开表之后,设定默认显示,需要在model中作如下配置
class UserType(models.Model): name = models.CharField(max_length=50) def __unicode__(self): return self.name
from django.contrib import admin from app01 import models class UserInfoAdmin(admin.ModelAdmin): list_display = ('username', 'password', 'email') admin.site.register(models.UserType) admin.site.register(models.UserInfo,UserInfoAdmin) admin.site.register(models.UserGroup) admin.site.register(models.Asset)
d、为数据表添加搜索功能
from django.contrib import admin from app01 import models class UserInfoAdmin(admin.ModelAdmin): list_display = ('username', 'password', 'email') search_fields = ('username', 'email')//添加搜索功能 admin.site.register(models.UserType) admin.site.register(models.UserInfo,UserInfoAdmin) admin.site.register(models.UserGroup) admin.site.register(models.Asset)
e、添加快速过滤
from django.contrib import admin from app01 import models class UserInfoAdmin(admin.ModelAdmin): list_display = ('username', 'password', 'email') search_fields = ('username', 'email') list_filter = ('username', 'email')//添加快速过滤功能 admin.site.register(models.UserType) admin.site.register(models.UserInfo,UserInfoAdmin) admin.site.register(models.UserGroup) admin.site.register(models.Asset)
学员管理系统练习
项目需求:
1.分讲师\学员\课程顾问角色,
2.学员可以属于多个班级,学员成绩按课程分别统计
3.每个班级至少包含一个或多个讲师
4.一个学员要有状态转化的过程 ,比如未报名前,报名后,毕业老学员
5.客户要有咨询纪录, 后续的定期跟踪纪录也要保存
6.每个学员的所有上课出勤情况\学习成绩都要保存
7.学校可以有分校区,默认每个校区的员工只能查看和管理自己校区的学员
8.客户咨询要区分来源
#_*_coding:utf-8_*_ from django.db import models # Create your models here. from django.core.exceptions import ValidationError from django.db import models from django.contrib.auth.models import User class_type_choices= (('online',u'网络班'), ('offline_weekend',u'面授班(周末)',), ('offline_fulltime',u'面授班(脱产)',), ) class UserProfile(models.Model): user = models.OneToOneField(User) name = models.CharField(u"姓名",max_length=32) def __unicode__(self): return self.name class School(models.Model): name = models.CharField(u"校区名称",max_length=64,unique=True) addr = models.CharField(u"地址",max_length=128) staffs = models.ManyToManyField('UserProfile',blank=True) def __unicode__(self): return self.name class Course(models.Model): name = models.CharField(u"课程名称",max_length=128,unique=True) price = models.IntegerField(u"面授价格") online_price = models.IntegerField(u"网络班价格") brief = models.TextField(u"课程简介") def __unicode__(self): return self.name class ClassList(models.Model): course = models.ForeignKey('Course') course_type = models.CharField(u"课程类型",choices=class_type_choices,max_length=32) semester = models.IntegerField(u"学期") start_date = models.DateField(u"开班日期") graduate_date = models.DateField(u"结业日期",blank=True,null=True) teachers = models.ManyToManyField(UserProfile,verbose_name=u"讲师") #def __unicode__(self): # return "%s(%s)" %(self.course.name,self.course_type) class Meta: verbose_name = u'班级列表' verbose_name_plural = u"班级列表" unique_together = ("course","course_type","semester") class Customer(models.Model): qq = models.CharField(u"QQ号",max_length=64,unique=True) name = models.CharField(u"姓名",max_length=32,blank=True,null=True) phone = models.BigIntegerField(u'手机号',blank=True,null=True) stu_id = models.CharField(u"学号",blank=True,null=True,max_length=64) #id = models.CharField(u"身份证号",blank=True,null=True,max_length=128) source_type = (('qq',u"qq群"), ('referral',u"内部转介绍"), ('51cto',u"51cto"), ('agent',u"招生代理"), ('others',u"其它"), ) source = models.CharField(u'客户来源',max_length=64, choices=source_type,default='qq') referral_from = models.ForeignKey('self',verbose_name=u"转介绍自学员",help_text=u"若此客户是转介绍自内部学员,请在此处选择内部学员姓名",blank=True,null=True,related_name="internal_referral") course = models.ForeignKey(Course,verbose_name=u"咨询课程") class_type = models.CharField(u"班级类型",max_length=64,choices=class_type_choices) customer_note = models.TextField(u"客户咨询内容详情",help_text=u"客户咨询的大概情况,客户个人信息备注等...") status_choices = (('signed',u"已报名"), ('unregistered',u"未报名"), ('graduated',u"已毕业"), ) status = models.CharField(u"状态",choices=status_choices,max_length=64,default=u"unregistered",help_text=u"选择客户此时的状态") consultant = models.ForeignKey(UserProfile,verbose_name=u"课程顾问") date = models.DateField(u"咨询日期",auto_now_add=True) class_list = models.ManyToManyField('ClassList',verbose_name=u"已报班级",blank=True) def __unicode__(self): return "%s,%s" %(self.qq,self.name ) class ConsultRecord(models.Model): customer = models.ForeignKey(Customer,verbose_name=u"所咨询客户") note = models.TextField(u"跟进内容...") status_choices = ((1,u"近期无报名计划"), (2,u"2个月内报名"), (3,u"1个月内报名"), (4,u"2周内报名"), (5,u"1周内报名"), (6,u"2天内报名"), (7,u"已报名"), ) status = models.IntegerField(u"状态",choices=status_choices,help_text=u"选择客户此时的状态") consultant = models.ForeignKey(UserProfile,verbose_name=u"跟踪人") date = models.DateField(u"跟进日期",auto_now_add=True) def __unicode__(self): return u"%s, %s" %(self.customer,self.status) class Meta: verbose_name = u'客户咨询跟进记录' verbose_name_plural = u"客户咨询跟进记录" class CourseRecord(models.Model): course = models.ForeignKey(ClassList,verbose_name=u"班级(课程)") day_num = models.IntegerField(u"节次",help_text=u"此处填写第几节课或第几天课程...,必须为数字") date = models.DateField(auto_now_add=True,verbose_name=u"上课日期") teacher = models.ForeignKey(UserProfile,verbose_name=u"讲师") def __unicode__(self): return u"%s 第%s天" %(self.course,self.day_num) class Meta: verbose_name = u'上课纪录' verbose_name_plural = u"上课纪录" unique_together = ('course','day_num') class StudyRecord(models.Model): course_record = models.ForeignKey(CourseRecord, verbose_name=u"第几天课程") student = models.ForeignKey(Customer,verbose_name=u"学员") record_choices = (('checked', u"已签到"), ('late',u"迟到"), ('noshow',u"缺勤"), ('leave_early',u"早退"), ) record = models.CharField(u"上课纪录",choices=record_choices,default="checked",max_length=64) score_choices = ((100, 'A+'), (90,'A'), (85,'B+'), (80,'B'), (70,'B-'), (60,'C+'), (50,'C'), (40,'C-'), (0,'D'), (-1,'N/A'), (-100,'COPY'), (-1000,'FAIL'), ) score = models.IntegerField(u"本节成绩",choices=score_choices,default=-1) date = models.DateTimeField(auto_now_add=True) note = models.CharField(u"备注",max_length=255,blank=True,null=True) def __unicode__(self): return u"%s,学员:%s,纪录:%s, 成绩:%s" %(self.course_record,self.student.name,self.record,self.get_score_display()) class Meta: verbose_name = u'学员学习纪录' verbose_name_plural = u"学员学习纪录" unique_together = ('course_record','student')