先看效果图:
登陆admin后的界面:
查看作者:
当然你也可以定制admin, 使界面更牛逼
数据库表结构: app01/models.py
1 from django.db import models
2 from django.utils.html import format_html #把字符串变成html
3
4 # Create your models here.
5 class Author(models.Model):
6 first_name = models.CharField(max_length=32)
7 last_name = models.CharField(max_length=32)
8 email = models.EmailField()
9
10 def __str__(self):
11 return "<%s %s>" % (self.first_name,self.last_name)
12
13 class Meta:
14 verbose_name_plural = u"作者"
15
16 class Publisher(models.Model):
17 name = models.CharField(max_length=64, unique=True)
18 address = models.CharField(max_length=128,null=True,blank=True)
19 city = models.CharField(max_length=64)
20 state_province = models.CharField(max_length=64,help_text="put your province here",verbose_name=u"所属省")
21 country = models.CharField(max_length=64,editable=False)
22 website = models.URLField()
23
24 def __str__(self):
25 return "<%s>" % (self.name)
26
27 class Book(models.Model):
28 name = models.CharField(max_length=128)
29 authors = models.ManyToManyField(Author) #书多对多到作者
30 publisher = models.ForeignKey(Publisher) #一对多
31 publish_date = models.DateField() #精确到天DateField()
32 status_choices = (("published", u"已出版"),
33 ("producing", u"待出版"),
34 ("forbidden", u"禁书"),
35 )
36 # 此时应该给个默认值,给之前没有status字段的书。
37 status = models.CharField(choices=status_choices, max_length=32, default="producing")
38
39 def __str__(self):
40 return "<%s %s>" % (self.name,self.publisher)
41
42
43 def colored_status(self):
44 if self.status == "published":
45 format_td = format_html("<span style='padding:2px;background-color:yellowgreen'>已出版</span>")
46 elif self.status == "producing":
47 format_td = format_html("<span style='padding:2px;background-color:red'>待出版</span>")
48 elif self.status == "forbidden":
49 format_td = format_html("<span style='padding:2px;background-color:yellow'>禁书</span>")
50
51 return format_td
52
53 colored_status.short_description = "STATUS" #页面显示为colored_status即方法名,这里改名为STATUS
现在你看到我直接贴代码,肯定不爽。好吧……
首先上面有三张表: Author(作者表)、Publisher(出版社表)、Book(图书表)。表与表的关联也很简单,一本书可由多个作者联合出,一个作者可出多本书,书与作者为ManyToMany关系;一本书只能由一个出版社出版,一个出版社可出多本书,一对多,用外键ForeignKey关联。
其它的__str__是啥?verbose_name是毛线东西? 看我之前的博客咯。
你登陆admin后其实是看不到3张表的,需要在admin.py注册一下:
1 from app01 import models
2
3 admin.site.register(models.Author)
4 admin.site.register(models.Book, BookAdmin)
5 admin.site.register(models.Publisher)
注册后再刷新页面,便可以看见表了。
一、form表单定制
在django进阶-1已经有下面这张图了,当你输入为空时,django会出现下面的error提示。
但现在你前端玩得很6,你觉得django自己的form表单so uglily,你想自己做个form表单(可用bootstrap美化),但又希望你做的表单有django的验证功能(重要!!)。so, How to do it?? 下面来自定制创建图书的form表单。
第一步: 创建form类
你定制的form表单可能有很多,应该建一个forms.py文件来存放定制的表单。
接下来在forms.py导入forms, 创建BookForm类(也可以命名为别的~)
1 from django import forms
2 from app01 import models
3
4 class BookForm(forms.Form):
5 name = forms.CharField(max_length=10)
6 # publisher_id = forms.IntegerField(widget=forms.Select)
7 publish_date = forms.DateField()
第二步: 处理用户请求
用户最开始请求数据是GET方式, 当输入数据后修改数据(创建图书),提交方式为POST
1 def book_form(request):
2 form = forms.BookForm() # 生成form实例
3 if request.method == "POST":
4 print(request.POST)
5 form = forms.BookForm(request.POST)
6 if form.is_valid(): #进行验证
7 print("form is ok")
8 print(form)
9 print(form.cleaned_data) #{'name': 'qq', 'publish_date': datetime.date(2017, 3, 14)}
10 form_data = form.cleaned_data
11 form_data["publisher_id"] = request.POST.get("publisher_id")
12 book_obj = models.Book(**form_data) #form_data为字典形式
13 book_obj.save()
14 else:
15 print(form.errors)
16 publisher_list = models.Publisher.objects.all()
17
18
19 return render(request, "app01/book_form.html", {"book_form":form,
20 "publishers":publisher_list})
当用户发起GET请求时,要生成一个空的form实例,并从数据库中查找所有的出版社publisher_list,之后进行渲染render. 接下来当然得写book_form.html啦。
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>Title</title>
6 </head>
7 <body>
8 <form action="" method="POST">{% csrf_token %}
9 {{ book_form }}
10 <select name="publisher_id">
11 {% for publisher in publishers %}
12 <option value="{{ publisher.id }}">{{ publisher.name }}</option>
13 {% endfor %}
14 </select>
15 <input type="submit" value="创建图书"/>
16 </form>
17 </body>
18 </html>
要是上面看不懂了,就别往下看了……可以看下我之前的博客哈。根据上面的html,会出现如下界面:
当你输入书名等信息,再点创建图书时,此时是以POST方式发起请求。
我们要将数据发给django强大的form表单进行验证(你可能没有输入或者日期输入为SB), 这些属于前端的验证,前端的验证是为了减轻后台服务器的压力。只需将请求的数据request.POST传给forms.py的BookForm()即可。
form = forms.BookForm(request.POST)
此时我们还需要进行后台验证,有可能成功,also可能失败。当验证成功时,form.is_valid返回true.
if form.is_valid(): #进行验证
验证成功后,自然是获取数据,存到数据库创建图书啦。好,信息是封装在form实例的,现打印form:
Print(form) <tr><th><label for="id_name">Name:</label></th><td><input id="id_name" maxlength="10" name="name" type="text" value="zcl_papa" required /></td></tr> <tr><th><label for="id_publish_date">Publish date:</label></th><td><input id="id_publish_date" name="publish_ date" type="text" value="2017-03-14" required /></td></tr>