django进阶-3

  先看效果图:

登陆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

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

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()即可。

1

form = forms.BookForm(request.POST)

此时我们还需要进行后台验证,有可能成功,also可能失败。当验证成功时,form.is_valid返回true.

1

if form.is_valid():   #进行验证

验证成功后,自然是获取数据,存到数据库创建图书啦。好,信息是封装在form实例的,现打印form:

View Code

擦,一堆html

要获取干净的数据,需处理一下:

1

form_data = form.cleaned_data

View Code

form表单定制ending.

  这里有个问题,为啥要在BookForm去掉publisher_id字段??

因为无法直接获取出版社的信息(下拉列表为空的),要想在前端界面有供选择出版社的input标签,需要自己在html添加

View Code

最后还需要将获得的信息加到字典(干净的数据)中,再添加到数据库。

呵呵,这比较麻烦,下面介绍更优化的方法。

    modelform

为了解决前面无法获取publisher_id的问题,引入modelform

modelform与form有很多相似之处的。接下来用modelform做个前端表单,当然,会丑点……

第一步: 

在forms.py创建类,继承forms.ModelForm:

可绑定Book表,Book表有什么字段,form表单就有什么字段,当然你也可以用fields使想显示的字段显示在界面。

 1 class BookModelForm(forms.ModelForm):

 2 

 3     class Meta:

 4         model = models.Book  #绑定Book类

 5         #fields = {"name", "publish_date"}  #只包括name,publish-date字段

 6         exclude = ()  #代表所有字段都包括

 7         widgets = {

 8             # 可以定义css样式,牛逼啊

 9             "name": forms.TextInput(attrs={"class":"form-control"}),

10         }

第二步: 处理用户请求

 1 def book_modelform(request):



子沐告诉你Python超炫的控制语句怎么写

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值