python的web框架 Django 讲解1

  • Django流程介绍
  • Django url
  • Django view
  • Django models
  • Django template
  • Django form
  • Django admin (后台数据库管理工具)

 

补充知识点:

  发送ajax提交时候的url的路径一定要加/ 

  

 $.ajax({
                url: '/index/',
                type: 'POST',
})

  

 

1 Django流程介绍

MTV模式      

        著名的MVC模式:所谓MVC就是把web应用分为模型(M),控制器(C),视图(V)三层;他们之间以一种插件似的,松耦合的方式连接在一起。

        模型负责业务对象与数据库的对象(ORM),视图负责与用户的交互(页面),控制器(C)接受用户的输入调用模型和视图完成用户的请求。

        

       Django的MTV模式本质上与MVC模式没有什么差别,也是各组件之间为了保持松耦合关系,只是定义上有些许不同,Django的MTV分别代表:

       Model(模型):负责业务对象与数据库的对象(ORM)

       Template(模版):负责如何把页面展示给用户

       View(视图):负责业务逻辑,并在适当的时候调用Model和Template

       此外,Django还有一个url分发器,它的作用是将一个个URL的页面请求分发给不同的view处理,view再调用相应的Model和Template

 

e

 

2 Django URL

URL配置(URLconf)就像Django 所支撑网站的目录。它的本质是URL模式以及要为该URL模式调用的视图函数之间的映射表;你就是以这种方式告诉Django,对于这个URL调用这段代码,对于那个URL调用那段代码。URL的家在是从配置文件中开始。

参数说明:

  • 一个正则表达式字符串
  • 一个可调用对象,通常为一个视图函数或一个指定视图函数路径的字符串
  • 可选的要传递给视图函数的默认参数(字典形式)
  • 一个可选的name参数

2.1  Here’s a sample URLconf:

from django.conf.urls import url
  
from . import views
  
urlpatterns = [
    url(r'^articles/2003/$', views.special_case_2003),
    url(r'^articles/([0-9]{4})/$', views.year_archive),
    url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
    url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
]
Notes:

To capture a value from the URL, just put parenthesis around it.
There’s no need to add a leading slash, because every URL has that. For example, it’s ^articles, not ^/articles.
The 'r' in front of each regular expression string is optional but recommended. It tells Python that a string is “raw” – that nothing in the string should be escaped. See Dive Into Python’s explanation.
Notes
Example requests:

A request to /articles/2005/03/ would match the third entry in the list. Django would call the functionviews.month_archive(request, '2005', '03').
/articles/2005/3/ would not match any URL patterns, because the third entry in the list requires two digits for the month.
/articles/2003/ would match the first pattern in the list, not the second one, because the patterns are tested in order, and the first one is the first test to pass. Feel free to exploit the ordering to insert special cases like this. Here, Django would call the function views.special_case_2003(request)
/articles/2003 would not match any of these patterns, because each pattern requires that the URL end with a slash.
/articles/2003/03/03/ would match the final pattern. Django would call the functionviews.article_detail(request, '2003', '03', '03').
Example requests:

2.2 Named groups

 

The above example used simple, non-named regular-expression groups (via parenthesis) to capture bits of the URL and pass them as positional arguments to a view. In more advanced usage, it’s possible to use named regular-expression groups to capture URL bits and pass them as keyword arguments to a view.

In Python regular expressions, the syntax for named regular-expression groups is (?P<name>pattern), where name is the name of the group and pattern is some pattern to match.

Here’s the above example URLconf, rewritten to use named groups:
The above example
import re

ret=re.search('(?P<id>\d{3})/(?P<name>\w{3})','weeew34ttt123/ooo')

print(ret.group())
print(ret.group('id'))
print(ret.group('name'))

  

from django.conf.urls import url
  
from . import views
  
urlpatterns = [
    url(r'^articles/2003/$', views.special_case_2003),
    url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
    url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive),
    url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.article_detail),
]
This accomplishes exactly the same thing as the previous example, with one subtle difference: The captured values are passed to view functions as keyword arguments rather than positional arguments. For example:

A request to /articles/2005/03/ would call the function views.month_archive(request, year='2005',month='03'), instead of views.month_archive(request, '2005', '03').
A request to /articles/2003/03/03/ would call the function views.article_detail(request, year='2003',month='03', day='03').
In practice, this means your URLconfs are slightly more explicit and less prone to argument-order bugs – and you can reorder the arguments in your views’ function definitions. Of course, these benefits come at the cost of brevity; some developers find the named-group syntax ugly and too verbose.
This accomplishes exactly the same thing as the previous example,

常见写法实例:

2.3  Captured arguments are always strings

Each captured argument is sent to the view as a plain Python string, regardless of what sort of match the regular expression makes. For example, in this URLconf line:

url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),

  ...the year argument passed to views.year_archive() will be a string,not an integer, even though the [0-9]{4} will only match integer strings.

2.4  Including other URLconfs 

At any point, your urlpatterns can “include” other URLconf modules. This essentially “roots” a set of URLs below other ones.

For example, here’s an excerpt of the URLconf for the Django website itself. It includes a number of other URLconfs:

from django.conf.urls import include, url
  
urlpatterns = [
    # ... snip ...
    url(r'^community/', include('django_website.aggregator.urls')),
    url(r'^contact/', include('django_website.contact.urls')),
    # ... snip ...
]

2.5 Passing extra options to view functions

URLconfs have a hook that lets you pass extra arguments to your view functions, as a Python dictionary.

The django.conf.urls.url() function can take an optional third argument which should be a dictionary of extra keyword arguments to pass to the view function.

For example:

from django.conf.urls import url
from . import views
  
urlpatterns = [
    url(r'^blog/(?P<year>[0-9]{4})/$', views.year_archive, {'foo': 'bar'}),
]

In this example, for a request to /blog/2005/, Django will call views.year_archive(request, year='2005',foo='bar').

This technique is used in the syndication framework to pass metadata and options to views.

Dealing with conflicts

It’s possible to have a URL pattern which captures named keyword arguments, and also passes arguments with the same names in its dictionary of extra arguments. When this happens, the arguments in the dictionary will be used instead of the arguments captured in the URL.

需要注意的是,当你加上参数时,对应函数views.index必须加上一个参数,参数名也必须命名为a,如下:

 

#应用:
 
if  auth():
 
    obj=model.user.filter()
 
{'obj':obj}

2.6 name param name的应用 

urlpatterns = [
    url(r'^index',views.index,name='bieming'),
    url(r'^admin/', admin.site.urls),
    # url(r'^articles/2003/$', views.special_case_2003),
    url(r'^articles/([0-9]{4})/$', views.year_archive),
    # url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
    # url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),

]
###################

def index(req):
    if req.method=='POST':
        username=req.POST.get('username')
        password=req.POST.get('password')
        if username=='alex' and password=='123':
            return HttpResponse("登陆成功")



    return render(req,'index.html')

#####################

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{#     <form action="/index/" method="post">#}
     <form action="{% url 'bieming' %}" method="post">
         用户名:<input type="text" name="username">
         密码:<input type="password" name="password">
         <input type="submit" value="submit">
     </form>
</body>
</html>


#######################

name的应用

 

3 Django Views(视图函数)

七  视图函数

http请求中产生两个核心对象:

http请求:HttpRequest对象

http响应:HttpResponse对象

所在位置:django.http

之前我们用到的参数request就是HttpRequest    检测方法:isinstance(request,HttpRequest)

 

1 HttpRequest对象的属性:

 

# path:       请求页面的全路径,不包括域名
#
# method:     请求中使用的HTTP方法的字符串表示。全大写表示。例如
#
#                    if  req.method=="GET":
#
#                              do_something()
#
#                    elseif req.method=="POST":
#
#                              do_something_else()
#
# GET:         包含所有HTTP GET参数的类字典对象
#
# POST:       包含所有HTTP POST参数的类字典对象
#
#              服务器收到空的POST请求的情况也是可能发生的,也就是说,表单form通过
#              HTTP POST方法提交请求,但是表单中可能没有数据,因此不能使用
#              if req.POST来判断是否使用了HTTP POST 方法;应该使用  if req.method=="POST"
#
#
#
# COOKIES:     包含所有cookies的标准Python字典对象;keys和values都是字符串。
#
# FILES:      包含所有上传文件的类字典对象;FILES中的每一个Key都是<input type="file" name="" />标签中                     name属性的值,FILES中的每一个value同时也是一个标准的python字典对象,包含下面三个Keys:
#
#             filename:      上传文件名,用字符串表示
#             content_type:   上传文件的Content Type
#             content:       上传文件的原始内容
#
#
# user:       是一个django.contrib.auth.models.User对象,代表当前登陆的用户。如果访问用户当前
#              没有登陆,user将被初始化为django.contrib.auth.models.AnonymousUser的实例。你
#              可以通过user的is_authenticated()方法来辨别用户是否登陆:
#              if req.user.is_authenticated();只有激活Django中的AuthenticationMiddleware
#              时该属性才可用
#
# session:    唯一可读写的属性,代表当前会话的字典对象;自己有激活Django中的session支持时该属性才可用。
HttpRequest对象的属性:

HttpRequest对象的方法:

  get_full_path(),   比如:http://127.0.0.1:8000/index33/?name=123 ,req.get_full_path()得到的结果就是/index33/?name=123

 

2 HttpResponse对象:

   对于HttpRequest对象来说,是由django自动创建的,但是,HttpResponse对象就必须我们自己创建。每个view请求处理方法必须返回一个HttpResponse对象。

  HttpResponse类在django.http.HttpResponse

  在HttpResponse对象上扩展的常用方法:页面渲染:render,render_to_response,

                                                        页面跳转:redirect

                                                        locals:   可以直接将函数中所有的变量传给模板    

   

 

4 Django Models

4.1 数据库配置  

1      django默认支持sqlite,mysql, oracle,postgresql数据库。

    <1> sqlite

            django默认使用sqlite的数据库,默认自带sqlite的数据库驱动

            引擎名称:django.db.backends.sqlite3

     <2>mysql

            引擎名称:django.db.backends.mysql

2    mysql驱动程序

          MySQLdb(mysql python)

          mysqlclient

          MySQL

          PyMySQL(纯python的mysql驱动程序)

3     在django的项目中会默认使用sqlite数据库,在settings里有如下设置:

           

              如果我们想要更改数据库,需要修改如下:

             

 

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME':'django_com',
        'USER':'root',
        'PASSWORD':'',
        'HOST':'',

    }
}
代码

注意:

     1 、NAME即数据库的名字,在mysql连接前该数据库必须已经创建,而上面的sqlite数据库下的db.sqlite3则是项目自动创建

         USER和PASSWORD分别是数据库的用户名和密码。

         设置完后,再启动我们的Django项目前,我们需要激活我们的mysql。

         然后,启动项目,会报错:no module named MySQLdb

         2、这是因为django默认你导入的驱动是MySQLdb可是MySQLdb对于py3有很大问题,所以我们需要的驱动是PyMySQL

         所以,我们只需要找到项目名文件下的__init__,在里面写入:

import pymysql

pymysql.install_as_MySQLdb()

  

         问题就解决了!

         这时就可以正常启动了。

        但此时数据库内并没有内容,我们需要做数据库的同步:

       


       为了更好的查询修改数据库,我们可以不使用Navicate,而是利用pycharm的Database(爱死pycharm啦)

       

      然后 ,安装MySQL的驱动(driver),这里需要创建一个密码(我的是123)安装成功后,

       

      填入数据库的名字,mysql的用户名和密码,然后就可以进行连接了。

       

      成功后点击右下角的apply和OK。

      这是你就可以看到数据库里的表和内容了:

       

      是不是很方便呢?

      如果你用的是sqlite数据库就更简单了,安装完驱动后,直接将sqlite拖动到Database就可以了:

      

 

4.2  Django的ORM(关系对象映射)

4.2.1  模型类的定义(一) 详细参见我的博客 sqlachmey

 

用于实现面向对象编程语言里不同类型系统的数据之间的转换,换言之,就是用面向对象的方式去操作数据库的创建表以及增删改查等操作。

 orm优点:

    1 ORM使得我们的通用数据库交互变得简单易行,而且完全不用考虑该死的SQL语句。快速开发,由此而来。

          2 可以避免一些新手程序猿写sql语句带来的性能问题。

            比如 我们查询User表中的所有字段:

            

           

    新手可能会用select * from  auth_user,这样会因为多了一个匹配动作而影响效率的。

  

 orm缺点:

    1 性能有所牺牲,不过现在的各种ORM框架都在尝试各种方法,比如缓存,延迟加载登来减轻这个问题。效果                 很显著。

           2 对于个别复杂查询,ORM仍然力不从心,为了解决这个问题,ORM一般也支持写raw sql。

 

4.2.2 Django ORM语法

  为了更好的理解,我们来做一个基本的 书籍/作者/出版商 数据库结构。 我们这样做是因为 这是一个众所周知的例子,很多SQL有关的书籍也常用这个举例。

实例:

我们来假定下面这些概念,字段和关系

作者模型:一个作者有姓名。

作者详细模型:把作者的详情放到详情表,包含性别,email地址和出生日期,作者详情模型和作者模型之间是一对一的关系(one-to-one)(类似于每个人和他的身份证之间的关系),在大多数情况下我们没有必要将他们拆分成两张表,这里只是引出一对一的概念。

出版商模型:出版商有名称,地址,所在城市,省,国家和网站。

书籍模型:书籍有书名和出版日期,一本书可能会有多个作者,一个作者也可以写多本书,所以作者和书籍的关系就是多对多的关联关系(many-to-many),一本书只应该由一个出版商出版,所以出版商和书籍是一对多关联关系(one-to-many),也被称作外键。

  

 

from __future__ import unicode_literals

from django.db import models

# Create your models here.

from django.db import models

class Publisher(models.Model):
    name = models.CharField(max_length=30, verbose_name="名称")
    address = models.CharField("地址", max_length=50)
    city = models.CharField('城市',max_length=60)
    state_province = models.CharField(max_length=30)
    country = models.CharField(max_length=50)
    website = models.URLField()

    class Meta:
        verbose_name = '出版商'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name

class Author(models.Model):
    name = models.CharField(max_length=30)
    def __str__(self):
        return self.name

class AuthorDetail(models.Model):
    sex = models.BooleanField(max_length=1, choices=((0, ''),(1, ''),))
    email = models.EmailField()
    address = models.CharField(max_length=50)
    birthday = models.DateField()
    author = models.OneToOneField(Author)

class Book(models.Model):
    title = models.CharField(max_length=100)
    authors = models.ManyToManyField(Author)
    publisher = models.ForeignKey(Publisher)
    publication_date = models.DateField()
    price=models.DecimalField(max_digits=5,decimal_places=2,default=10)
    def __str__(self):
        return self.title
对应models代码

 

注意:

  记得在settings里的INSTALLED_APPS中加入'app01',然后同步数据库:

 

分析代码:

        1  每个数据模型都是django.db.models.Model的子类,它的父类Model包含了所有必要的和数据库交互的方法。并提供了一个简介漂亮的定义数据库字段的语法。

        2  每个模型相当于单个数据库表(多对多关系例外,会多生成一张关系表),每个属性也是这个表中的字段。属性名就是字段名,它的类型(例如CharField)相当于数据库的字段类型(例如varchar)。大家可以留意下其它的类型

都和数据库里的什么字段对应。

         3  模型之间的三种关系:一对一,一对多,多对多。

             一对一:实质就是在主外键(author_id就是foreign key)的关系基础上,给外键加了一个UNIQUE的属性;

  一对一:实质就是在主外键(author_id就是foreign key)的关系基础上,给外键加了一个UNIQUE的属性;

           

            一对多:就是主外键关系;

                               

           

             多对多:

                     book类里定义了一个多对多的字段authors,并没在book表中,这是因为创建了一张新的表:

                                              

         4  模型的常用字段类型以及参数:

# AutoField
# 一个 IntegerField, 添加记录时它会自动增长. 你通常不需要直接使用这个字段; 如果你不指定主键的话,系统会自动添加一个主键字段到你的 model.(参阅 _自动主键字段)
# BooleanField
# A true/false field. admin 用 checkbox 来表示此类字段.
# CharField
# 字符串字段, 用于较短的字符串.
# 
# 如果要保存大量文本, 使用 TextField.
# 
# admin 用一个 <input type="text"> 来表示此类字段 (单行输入).
# 
# CharField 要求必须有一个参数 maxlength, 用于从数据库层和Django校验层限制该字段所允许的最大字符数.
# 
# CommaSeparatedIntegerField
# 用于存放逗号分隔的整数值. 类似 CharField, 必须要有 maxlength 参数.
# DateField
# 一个日期字段. 共有下列额外的可选参数:
# 
# Argument    描述
# auto_now    当对象被保存时,自动将该字段的值设置为当前时间.通常用于表示 "last-modified" 时间戳.
# auto_now_add    当对象首次被创建时,自动将该字段的值设置为当前时间.通常用于表示对象创建时间.
# admin 用一个文本框 <input type="text"> 来表示该字段数据(附带一个 JavaScript 日历和一个"Today"快键.
# 
# DateTimeField
#  一个日期时间字段. 类似 DateField 支持同样的附加选项.
# admin 用两上文本框 <input type="text"> 表示该字段顺序(附带JavaScript shortcuts). 
# 
# EmailField
# 一个带有检查 Email 合法性的 CharField,不接受 maxlength 参数.
# FileField
# 一个文件上传字段.
# 
# 要求一个必须有的参数: upload_to, 一个用于保存上载文件的本地文件系统路径. 这个路径必须包含 strftime formatting, 该格式将被上载文件的 date/time 替换(so that uploaded files don't fill up the given directory).
# 
# admin 用一个``<input type="file">``部件表示该字段保存的数据(一个文件上传部件) .
# 
# 在一个 model 中使用 FileField 或 ImageField 需要以下步骤:
# 
# 在你的 settings 文件中, 定义一个完整路径给 MEDIA_ROOT 以便让 Django在此处保存上传文件. (出于性能考虑,这些文件并不保存到数据库.) 定义 MEDIA_URL 作为该目录的公共 URL. 要确保该目录对 WEB 服务器用户帐号是可写的.
# 在你的 model 中添加 FileField 或 ImageField, 并确保定义了 upload_to 选项,以告诉 Django 使用 MEDIA_ROOT 的哪个子目录保存上传文件.
# 你的数据库中要保存的只是文件的路径(相对于 MEDIA_ROOT). 出于习惯你一定很想使用 Django 提供的 get_<fieldname>_url 函数.举例来说,如果你的 ImageField 叫作 mug_shot, 你就可以在模板中以 {{ object.get_mug_shot_url }} 这样的方式得到图像的绝对路径.
# FilePathField
# 可选项目为某个特定目录下的文件名. 支持三个特殊的参数, 其中第一个是必须提供的.
# 
# 参数    描述
# path    必需参数. 一个目录的绝对文件系统路径. FilePathField 据此得到可选项目. Example: "/home/images".
# match    可选参数. 一个正则表达式, 作为一个字符串, FilePathField 将使用它过滤文件名. 注意这个正则表达式只会应用到 base filename 而不是路径全名. Example: "foo.*\.txt^", 将匹配文件 foo23.txt 却不匹配 bar.txt 或 foo23.gif.
# recursive    可选参数.要么 True 要么 False. 默认值是 False. 是否包括 path 下面的全部子目录.
# 这三个参数可以同时使用.
# 
# 我已经告诉过你 match 仅应用于 base filename, 而不是路径全名. 那么,这个例子:
# 
# FilePathField(path="/home/images", match="foo.*", recursive=True)
# ...会匹配 /home/images/foo.gif 而不匹配 /home/images/foo/bar.gif
# 
# FloatField
# 一个浮点数. 必须 提供两个 参数:
# 
# 参数    描述
# max_digits    总位数(不包括小数点和符号)
# decimal_places    小数位数
# 举例来说, 要保存最大值为 999 (小数点后保存2位),你要这样定义字段:
# 
# models.FloatField(..., max_digits=5, decimal_places=2)
# 要保存最大值一百万(小数点后保存10位)的话,你要这样定义:
# 
# models.FloatField(..., max_digits=19, decimal_places=10)
# admin 用一个文本框(<input type="text">)表示该字段保存的数据.
# 
# ImageField
# 类似 FileField, 不过要校验上传对象是否是一个合法图片.它有两个可选参数:height_field 和 width_field,如果提供这两个参数,则图片将按提供的高度和宽度规格保存.
# 
# 该字段要求 Python Imaging Library.
# 
# IntegerField
# 用于保存一个整数.
# 
# admin 用一个``<input type="text">``表示该字段保存的数据(一个单行编辑框)
# 
# IPAddressField
# 一个字符串形式的 IP 地址, (i.e. "24.124.1.30").
# 
# admin 用一个``<input type="text">``表示该字段保存的数据(一个单行编辑框)
# 
# NullBooleanField
# 类似 BooleanField, 不过允许 NULL 作为其中一个选项. 推荐使用这个字段而不要用 BooleanField 加 null=True 选项.
# 
# admin 用一个选择框 <select> (三个可选择的值: "Unknown", "Yes" 和 "No" ) 来表示这种字段数据.
# 
# PhoneNumberField
# 一个带有合法美国风格电话号码校验的 CharField``(格式: ``XXX-XXX-XXXX).
# PositiveIntegerField
# 类似 IntegerField, 但取值范围为非负整数(这个字段应该是允许0值的....所以字段名字取得不太好,无符号整数就对了嘛).
# PositiveSmallIntegerField
# 类似 PositiveIntegerField, 取值范围较小(数据库相关)
# SlugField
# "Slug" 是一个报纸术语. slug 是某个东西的小小标记(短签), 只包含字母,数字,下划线和连字符.它们通常用于URLs.
# 
# 若你使用 Django 开发版本,你可以指定 maxlength. 若 maxlength 未指定, Django 会使用默认长度: 50. 在以前的 Django 版本,没有任何办法改变 50 这个长度.
# 
# 这暗示了 db_index=True.
# 
# 它接受一个额外的参数: prepopulate_from, which is a list of fields from which to auto-populate the slug, via JavaScript, in the object's admin form:
# 
# models.SlugField(prepopulate_from=("pre_name", "name"))
# prepopulate_from 不接受 DateTimeFields.
# 
# admin 用一个``<input type="text">``表示 SlugField 字段数据(一个单行编辑框) 
# 
# SmallIntegerField
# 类似 IntegerField, 不过只允许某个取值范围内的整数.(依赖数据库)
#  
# TextField
# 一个容量很大的文本字段.
# 
# admin 用一个 <textarea> (文本区域)表示该字段数据.(一个多行编辑框).
# 
# TimeField
# A time. Accepts the same auto-population options as DateField 和 DateTimeField.
# 
# admin 用一个 <input type="text"> 文本框表示该字段保存的数据(附加一些JavaScript shortcuts).
# 
# URLField
# 用于保存 URL. 若 verify_exists 参数为 True (默认), 给定的 URL 会预先检查是否存在(即URL是否被有效装入且没有返回404响应).
# 
# admin 用一个 <input type="text"> 文本框表示该字段保存的数据(一个单行编辑框)
# 
# USStateField
# 一个两字母的美国州名缩写.
# 
# admin 用一个 <input type="text"> 文本框表示该字段保存的数据(一个单行编辑框)
# 
# XMLField
# 一个校验值是否为合法XML的 TextField,必须提供参数: schema_path, 它是一个用来校验文本的 RelaxNG schema 的文件系统路径.
django orm模型的常用字段类型以及参数:

4.2.1  模型类的定义(二)      

一  定义数据模型的扩展属性

     通过内部类Meta给数据模型类增加扩展属性:

     class Meta:

             verbose_name='名称'      #表名由英文转换成中文了

             verbose_name_plural='名称复数形式'

             ordering='排序字段'   

2 admin 用户引入

# 生成表并写入数据库
python manage.py makemigrations
python manage.py migrate

python manage.py createsuperuser  # 创建超级管理员

  

    创建超级用户后,登录admin发现我们定义的表并不在,我们需要对所创建的表(类)进行注册:

 

#admin.py
# Register your models here.
from django.contrib import admin
from app01.models import *
# @admin.register(Publisher)
class PubAdmin(admin.ModelAdmin):
    list_display = ("name","country","city")
    search_fields = ('name','city')
    list_filter = ('state_province',)
    ordering = ('name',)
    # fields = ('name','address',)
    # exclude = ('name','address')
    fieldsets = (
        (None,{'fields':('name',"address")}),
        ("Advanced options",{'classes':('collapse',),
                             'fields' :('city','country','website')

                             })
    )

admin.site.register(Author)
admin.site.register(AuthorDetail)
admin.site.register(Publisher,PubAdmin)
admin.site.register(Book)
对应代码

 

 

 

这是因为:

          

 

 

4.3 ORM常用操作

4.3.1 增加

    create和save方法

实例:

 

 

>>> from app01.models import *
>>> Author.objects.create(name='Alvin')
<Author: Alvin>
>>> AuthorDetail.objects.create(sex=False,email='916852314@qq.com',address='bejing',birthday='1995-3-16',author_id=1)
<AuthorDetail: AuthorDetail object>
>>> pub=Publisher()
>>> pub.name='河大出版社'
>>> pub.address='保定'
>>> pub.city='保定'
>>> pub.state_province='河北'
>>> pub.country='China'
>>> pub.website='http://www.beida.com'
>>> pub.save()

对应代码

  注意:如果每次创建一个对象,想显示对应的raw sql,需要在settings加上日志记录部分:

LOGGING = {
#     'version': 1,
#     'disable_existing_loggers': False,
#     'handlers': {
#         'console':{
#             'level':'DEBUG',
#             'class':'logging.StreamHandler',
#         },
#     },
#     'loggers': {
#         'django.db.backends': {
#             'handlers': ['console'],
#             'propagate': True,
#             'level':'DEBUG',
#         },
#     }
# }

 

那么如何插入存在外键和多对多关系的一本书的信息呢?

 

>>> Book.objects.create(title='php',publisher=pub,publication_date='2017-7-7')
<Book: php>
>>> author1=Author.objects.get(id=1)
>>> author2=Author.objects.get(name='alvin')
>>> book=Book.objects.get(id=1)
>>> book.authors.add(author1,author1)
>>> book.authors.add(author1,author2)

  

  

 

posted @ 2016-08-20 22:01  众里寻,阑珊处  阅读(456)  评论(0编辑  收藏  举报
返回顶部