首页 > 其他 > 详细

Django之MTV

时间:2018-04-17 00:27:10      阅读:75      评论:0      收藏:0      [点我收藏+]

标签:url django views

一、简单演示

返回当前时间

url.py文件内容:

from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^timmer/', views.timmer),
]


views.py文件内容:

from django.shortcuts import render,HttpResponse,redirect
def timmer(request):
    import time
    ctime=time.time()
    # return HttpResponse (ctime)          #只能返回字符串
    return render(request,"timmer.html", {"ctime":ctime})     #返回html,这样就能定义返回的样式


timmer.html文件内容:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>timmer</title>
    < style >
        p{
        color: red;
        }
    </style>
</head>
<body>

{#双大括号是模板语法,里面是变量,接受views.py的参数#}
<p>当前时间:{{ ctime }}</p>
</body>
</html>


二、url控制器

1、url的分组

urls.py文件内容:

from django.conf.urls import url,include
from django.contrib import admin
from django.shortcuts import HttpResponse
from app01.views import *
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^timer/$', timer),                                        # timer(request)
    #分组
    url(r'^books_achrive/(\d+)/$', book_detail),              # book_detail(request,3)
    url(r'^books_achrive/(\d+)/(\d+)/$', books_achrive),        # books_achrive(request,2012,12)
    #有名分组books_achrive后面有一个year组和一个month组
    url(r'^books_achrive/(?P<year>\d+)/(?P<month>\d+)/$', books_achrive2), # books_achrive(request,year=2012,month=12)
]

views.py文件内容:

from django.shortcuts import render,HttpResponse,redirect
def book_detail(reqeust,id):
    return HttpResponse(id)
    
def books_achrive(request,year,month):
    return HttpResponse(year+":"+month)
    
def books_achrive2(request,month,year):
    return HttpResponse(year+":"+month)


这样用户访问的路径为/books_achrive/2012/12/时,就会在URL匹配到url(r'^books_achrive/(\d+)/(\d+)/$', books_achrive),然后执行books_achrive函数

2、url的分发


在项目下的urls.py文件里面定义连接到具体的应用的路径

url(r'^app01/', include('app01.urls'), ),

然后在具体应用的urls.py文件里面定义具体的url

from django.conf.urls import url,include
from app01.views import *
urlpatterns = [
    url(r'^timer/$', timer), # timer(request)
    url(r'^books_achrive/(\d+)/$', book_detail), # book_detail(request,3)
    url(r'^books_achrive/(?P<year>\d+)/(?P<month>\d+)/$', books_achrive2), # books_achrive(request,year=2012,month=12)
]


3、URL 的反向解析


在使用Django 项目时,一个常见的需求是获得URL 的最终形式,以用于嵌入到生成的内容中(视图中和显示给用户的URL等)或者用于处理服务器端的导航(重定向等)。

人们强烈希望不要硬编码这些URL(费力、不可扩展且容易产生错误)或者设计一种与URLconf 毫不相关的专门的URL 生成机制,因为这样容易导致一定程度上产生过期的URL。

换句话讲,需要的是一个DRY 机制。除了其它有点,它还允许设计的URL 可以自动更新而不用遍历项目的源代码来搜索并替换过期的URL。


在需要URL 的地方,对于不同层级,Django 提供不同的工具用于URL 反查:

(1)在模板中:使用url 模板标签。

from django.conf.urls import url
from . import views
urlpatterns = [
        url(r'^articles/([0-9]{4})/$', views.year_archive, name='news-year-archive'),
]

在模板的代码中使用下面的方法获得它们:

<a href="{% url 'news-year-archive' 2012 %}">2012 Archive</a>

<ul>
{% for yearvar in year_list %}
<li><a href="{% url 'news-year-archive' yearvar %}">{{ yearvar }} Archive</a></li>
{% endfor %}
</ul>

(2)在Python 代码中:使用django.core.urlresolvers.reverse() 函数。

from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect

def redirect_to_year(request):
    year = 2006.
    return HttpResponseRedirect(reverse('news-year-archive', args=(year,)))


(3)在更高层的与处理Django 模型实例相关的代码中:使用get_absolute_url() 方法。


4、反向解析示例:登录页面

urls.py文件内容:

from django.conf.urls import url,include
from django.contrib import admin
from django.shortcuts import render,HttpResponse,redirect
from app01.views import *

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^login/', login,name="xxx"),     #定义url的别名xxx
]

views.py文件内容:

from django.shortcuts import render,HttpResponse,redirect

def login(request):
    if request.method=="GET":
        print(request.GET)
        print(request.POST)
        print(request.method)
        print(request.path)
        print(request.path_info)
        print(request.body)
        return render(request, "login.html")
    else:
        user=request.POST.get("user")
        pwd=request.POST.get("pwd")
        
        if 1:                                    #用户输入的用户名和密码与数据库里面的做对比,判断是否一致
            return redirect("/app01/timer/")

登录页面login.html文件内容:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        p{
            color: red;
        }
    </style>
</head>
<body>

<form action="{% url 'xxx' %}" method="post">
    {% csrf_token %}                                  #解决出现Forbidden (403)错误
    <p>用户名 <input type="text" name="user"></p>
    <p>密码 <input type="password" name="pwd"></p>
    <input type="submit">
</form>

</body>
</html>

利用反向解析的好处:访问的时候用url的别名可以避免了随着url的变化而访问路径跟着变化


三、视图层之视图函数(views)

1、HttpRequest对象的属性

(1)HttpRequest.body

  一个字符串,代表请求报文的主体。在处理非 HTTP 形式的报文时非常有用,例如:二进制图片、XML,Json等。

  但是,如果要处理表单数据的时候,推荐还是使用 HttpRequest.POST 。

(2)HttpRequest.path

  一个字符串,表示请求的路径组件(不含域名)。

  例如:"/music/bands/the_beatles/"

(3)HttpRequest.method

  一个字符串,表示请求使用的HTTP方法。必须使用大写。

  例如:"GET"、"POST"

(4)HttpRequest.encoding

  一个字符串,表示提交的数据的编码方式(如果为None则表示使用DEFAULT_CHARSET的设置,默认为'utf-8')。

这个属性是可写的,你可以修改它来修改访问表单数据使用的编码。

接下来对属性的任何访问(例如从GET或POST中读取数据)将使用新的encoding值。

如果你知道表单数据的编码不是DEFAULT_CHARSET ,则使用它。


(5)HttpRequest.GET

  一个类似于字典的对象,包含HTTP、GET的所有参数。详情请参考QueryDict对象。


(6)HttpRequest.POST

  一个类似于字典的对象,如果请求中包含表单数据,则将这些数据封装成QueryDict对象。

  POST请求可以带有空的POST字典 —— 如果通过HTTPPOST方法发送一个表单,但是表单中没有任何的数据,QueryDict对象依然会被建。

因此,不应该使用 if request.POST来检查使用的是否是POST方法;应该使用 if request.method == "POST"

  另外:如果使用POST上传文件的话,文件信息将包含在FILES属性中。


(7)HttpRequest.REQUEST

  一个类似于字典的对象,它首先搜索POST,然后搜索GET,主要是为了方便。灵感来自于PHP的 $_REQUEST。

  例如,如果GET = {"name": "john"}而POST = {"age": '34'} , REQUEST["name"]将等于"john", REQUEST["age"]将等于"34"。

  强烈建议使用GET和POST而不要用REQUEST,因为它们更加明确。


(8)HttpRequest.COOKIES

  一个标准的Python字典,包含所有的cookie。键和值都为字符串。


(9)HttpRequest.FILES

  一个类似于字典的对象,包含所有的上传文件信息。

   FILES 中的每个键为<input type="file" name="" /> 中的name,值则为对应的数据。


  注意,FILES 只有在请求的方法为POST 且提交的<form> 带有enctype="multipart/form-data" 的情况下才会包含数据。否则,FILES 将为一个空的类似于字典的对象。

(10)HttpRequest.META

   一个标准的Python 字典,包含所有的HTTP 首部。具体的头部信息取决于客户端和服务器,下面是一些示例:


    CONTENT_LENGTH —— 请求的正文的长度(是一个字符串)。

    CONTENT_TYPE —— 请求的正文的MIME 类型。

    HTTP_ACCEPT —— 响应可接收的Content-Type。

    HTTP_ACCEPT_ENCODING —— 响应可接收的编码。

    HTTP_ACCEPT_LANGUAGE —— 响应可接收的语言。

    HTTP_HOST —— 客服端发送的HTTP Host 头部。

    HTTP_REFERER —— Referring 页面。

    HTTP_USER_AGENT —— 客户端的user-agent 字符串。

    QUERY_STRING —— 单个字符串形式的查询字符串(未解析过的形式)。

    REMOTE_ADDR —— 客户端的IP 地址。

    REMOTE_HOST —— 客户端的主机名。

    REMOTE_USER —— 服务器认证后的用户。

    REQUEST_METHOD —— 一个字符串,例如"GET" 或"POST"。

    SERVER_NAME —— 服务器的主机名。

    SERVER_PORT —— 服务器的端口(是一个字符串)。

   从上面可以看到,除 CONTENT_LENGTH 和 CONTENT_TYPE 之外,请求中的任何 HTTP 首部转换为 META 的键时,

    都会将所有字母大写并将连接符替换为下划线最后加上 HTTP_  前缀。

    所以,一个叫做 X-Bender 的头部将转换成 META 中的 HTTP_X_BENDER 键。


(11)HttpRequest.user

  一个AUTH_USER_MODEL类型的对象,表示当前登录的用户。

  如果用户当前没有登录,user将设置为django.contrib.auth.models.AnonymousUser的一个实例。你可以通过is_authenticated()区分它们。


例如:

if request.user.is_authenticated():
# Do something for logged-in users.
else:
    # Do something for anonymous users.

  

user 只有当Django启用AuthenticationMiddleware中间件时才可用。


(12)HttpRequest.session

      一个既可读又可写的类似于字典的对象,表示当前的会话。只有当Django启用会话的支持时才可用。


(13)HttpRequest.resolver_match

      一个ResolverMatch的实例,表示解析后的URL。这个属性只有在URL解析方法之后才设置,这意味着它在所有的视图中可以访问,

    但是在URL解析发生之前执行的中间件方法中不可以访问(比如process_request,但你可以使用process_view代替)。


四、MTV模型

Django的MTV分别代表:

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

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

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

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


1、模板层(template)

from django.conf.urls import url,include
from django.contrib import admin
from django.shortcuts import HttpResponse
from app01.views import *

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^template/', temp_func,),
]

views.py文件内容:

def temp_func(request):

    l=[11,222,333]
    dic={"name":"yuan","age":23}
    
    class Person(object):
        def __init__(self,name,age):
            self.name=name
            self.age=age
        def learning(self):
             return "learning"
    alex=Person("alex",45)
    egon=Person("egon",36)
    person_list=[alex,egon]
    
    import datetime
    now=datetime.datetime.now()
    print(now)
    
    file_size=234212123
    content="hello yuan world text"
    s="<a href='http://www.baidu.com'>hello</a>"
    #return render(request,"temp.html",{"l":l,"dic":dic})
    return render(request,"temp.html",locals())

app01应用下创建templatetags模块(文件夹),里面创建my_filters_tags.py文件,内容如下:

@register.filter
def multi_filter(x,y):
    return x * y
@register.simple_tag
def multi_tag(x,y):
    return x * y

temp.html文件内容:

{% load my_filters_tags %}
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<h3>变量</h3>
<p>{{ l }}</p>                             {#  结果是:[11, 222, 333]    #}
<p>{{ l.1 }}</p>                           {#  结果是:222   #}
<p>{{ dic }}</p>                            {#  结果是:{'name': 'yuan', 'age': 23}   #}
<p>{{ dic.name }}</p>                       {#  结果是:yuan   #}
<p>{{ alex.age }}</p>                       {#  结果是:45   #}


<h3>过滤器</h3>                           {#  语法;{{obj|filter__name:param}}   #}
<p>{{ l.1|add:100 }}</p>                     {#  结果是:322   #}
<p>{{ now|date:"Y-m-d" }}</p>                 {#  结果是:2018-04-16   #}
<p>{{ file_size|filesizeformat }}</p>           {#  结果是:223.4 MB   #}
<p>{{ content|truncatechars:12 }}</p>           {#  结果是:hello yua...  加上点号一共显示12个字符 #}
<p>{{ content|truncatewords:2 }}</p>            {#  结果是:hello yuan ...  显示两个单词#}
<p>{{ content|slice:"2:-1" }}</p>              {#  结果是:llo yuan world tex  #}
<p>{{ s|safe }}</p>                        {#  结果是:hello   告诉Django这段代码是安全的不必转义#}


<h3>标签</h3>
{% for person in person_list %}                {#  for循环person_list列表   #}
   <p>{{ forloop.counter0 }} {{ person.name }}:{{ person.age }} --- {{ person.learning }}</p>
{% endfor %}
{#  {{ forloop.counter0 }} 可以取到循环序号  #}

{#  如果变量l.0 > 100,就显示100,否则显示变量l.0    #}
{% if l.0 > 100 %}
    <p>100</p>
 {% else %}
    <p>{{ l.0 }}</p>
{% endif %}


<h4>自定义过滤器或者标签</h4>
{{ l.0|multi_filter:2 }}                          {#  结果是:22   #}
{% multi_tag l.0|add:12 10 %}                     {#  结果是:230   #}
</body>
</html>

五、Django-model基础


1、在settings.py配置下面内容可以查看翻译成的sql语句

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

2、创建模型

class Author(models.Model):                            #Author表包含 nid、name、age、 authorDetail字段
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    # 与AuthorDetail建立一对一的关系
    authorDetail = models.OneToOneField(to="AuthorDetail")
    
class AuthorDetail(models.Model):                        #AuthorDetail表包含nid、birthday、telephone、addr字段
    nid = models.AutoField(primary_key=True)
    birthday = models.DateField()
    telephone = models.BigIntegerField()
    addr = models.CharField(max_length=64)
    
class Publish(models.Model):                             #Publish表包含nid、name、city、email字段
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    city = models.CharField(max_length=32)
    email = models.EmailField()
    
class Book(models.Model):                               #Book表包含nid、title、publishDate、price、keepNum、publish字段
    nid = models.AutoField(primary_key=True)
    title = models.CharField(max_length=32)
    publishDate = models.DateField()
    price = models.DecimalField(max_digits=5, decimal_places=2)
    keepNum = models.IntegerField() < br > commentNum = models.IntegerField()
    # 与Publish建立一对多的关系,外键字段建立在多的一方
    publish = models.ForeignKey(to="Publish", to_field="nid")
    # 与Author表建立多对多的关系,ManyToManyField可以建在两个模型中的任意一个,自动创建第三张表
    authors = models.ManyToManyField(to='Author') 

3、字段选项

(1)null

如果为True,Django将用NULL来在数据库中存储空值。 默认值是False.

(2)blank

如果为True,该字段允许不填。默认为False。要注意,这与null不同。null纯粹是数据库范畴的,而blank是数据验证范畴的。

如果一个字段的blank = True,表单的验证将允许该字段是空值。如果字段的blank = False,该字段就是必填的。

(3)default

字段的默认值。可以是一个值或者可调用对象。如果可调用 ,每有新对象被创建它都会被调用。

(4)primary_key

如果为True,那么这个字段就是模型的主键。如果你没有指定任何一个字段的primary_key = True,Django就会自动添加一个IntegerField字段做为主键,所以除非你想覆盖默认的主键行为,否则没必要设置任何一个字段的primary_key = True。

(5)unique

如果该值设置为True, 这个数据字段的值在整张表中必须是唯一的

(6)choices

由二元组组成的一个可迭代对象(例如,列表或元组),用来给字段提供选择项。 如果设置了choices ,默认的表单将是一个选择框而不是标准的文本框,而且这个选择框的选项就是choices 中的选项。


4、添加表记录

(1)普通字段

    #1、方式1
    publish_obj = Publish(name="人民出版社", city="北京", email="renMin@163.com")
    publish_obj.save()  # 将数据保存到数据库
    #2、方式2 < br > 返回值publish_obj是添加的记录对象
    publish_obj = Publish.objects.create(name="人民出版社", city="北京",
                                         email="renMin@163.com") < br > < br > 方式3 < br > 表.objects.create(**request.POST.dict())

(2)外键字段

    #1、方式1:
    publish_obj = Publish.objects.get(nid=1)
    Book.objects.create(title="西游记", publishDate="2012-12-12", price=665, pageNum=334, publish=publish_obj)
    #2、方式2:
    Book.objects.create(title="西游记", publishDate="2012-12-12", price=665, pageNum=334, publish_id=1) 

(3)多对多字段

    book_obj = Book.objects.create(title="追风筝的人", publishDate="2012-11-12", price=69, pageNum=314, publish_id=1)
    author_yuan = Author.objects.create(name="yuan", age=23, authorDetail_id=1)
    author_egon = Author.objects.create(name="egon", age=32, authorDetail_id=2)
    book_obj.authors.add(author_egon, author_yuan)  # 将某个特定的 model 对象添加到被关联对象集合中。   =======    book_obj.authors.add(*[])
    book_obj.authors.create()  # 创建并保存一个新对象,然后将这个对象加被关联对象的集合中,然后返回这个新对象。
    
解除关系:
    book_obj.authors.remove()     # 将某个特定的对象从被关联对象集合中去除。    ======   book_obj.authors.remove(*[])
    book_obj.authors.clear()       #清空被关联对象集合。

5、查询表记录

(1)查询相关API

< 1 > all():                        查询所有结果

< 2 > filter(**kwargs):             它包含了与所给筛选条件相匹配的对象

< 3 > get(**kwargs):                返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。

< 4 > exclude(**kwargs):            它包含了与所给筛选条件不匹配的对象

< 5 > values(*field):               返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列model的实例化对象,而是一个可迭代的字典序列

< 6 > values_list(*field):          它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列

< 7 > order_by(*field):              对查询结果排序

< 8 > reverse():                    对查询结果反向排序

< 9 > distinct():                   从返回结果中剔除重复纪录

< 10 > count():                     返回数据库中匹配查询(QuerySet)的对象数量。

< 11 > first():                     返回第一条记录

< 12 > last():                      返回最后一条记录

< 13 > exists():                    如果QuerySet包含数据,就返回True,否则返回False


(2)双下划线之单表查询

models.Tb1.objects.filter(id__lt=10, id__gt=1)       # 获取id大于1 且 小于10的值
models.Tb1.objects.filter(id__in=[11, 22, 33])      # 获取id等于11、22、33的数据
models.Tb1.objects.exclude(id__in=[11, 22, 33])     # not in
models.Tb1.objects.filter(name__contains="ven")
models.Tb1.objects.filter(name__icontains="ven")   # icontains大小写不敏感
models.Tb1.objects.filter(id__range=[1, 2])         # 范围bettwen and

startswith,istartswith, endswith, iendswith 

(3)基于对象的跨表查询

< 1 >一对多查询(Publish 与 Book)

正向查询(按字段:publish):
# 查询nid=1的书籍的出版社所在的城市<br>
book_obj=Book.objects.get(nid=1)<br>print(book_obj.publish.city) # book_obj.publish 是nid=1的书籍对象关联的出版社对象
 
反向查询(按表名:book_set):
# 查询 人民出版社出版过的所有书籍
publish = Publish.objects.get(name="人民出版社")
book_list = publish.book_set.all()          # 与人民出版社关联的所有书籍对象集合
for book_obj in book_list:
    print(book_obj.title)

< 2 >一对一查询

正向查询(按字段:authorDetail):
# 查询egon作者的手机号
author_egon = Author.objects.get(name="egon")
print(author_egon.authorDetail.telephone)

反向查询(按表名:author):
# 查询所有住址在北京的作者的姓名
authorDetail_list = AuthorDetail.objects.filter(addr="beijing")
for obj in authorDetail_list:
    print(obj.author.name)

< 3 >多对多查询

正向查询(按字段:authors):
book_obj = Book.objects.filter(title="西游记").first()
authors = book_obj.authors.all()
for author_obj in authors:
    print(author_obj.name, author_obj.authorDetail.telephone)
    
反向查询(按表名:book_set):
# 查询egon出过的所有书籍的名字
author_obj = Author.objects.get(name="egon")
book_list = author_obj.book_set.all()       # 与egon作者相关的所有书籍
for book_obj in book_list:
    print(book_obj.title)
    
    
#查询 人民出版社出版过的所有书籍
publish = Publish.objects.get(name="人民出版社")
book_list = publish.bookList.all()          # 与人民出版社关联的所有书籍对象集合

(4)基于双下划线的跨表查询

# 练习1:  查询人民出版社出版过的所有书籍的名字与价格(一对多)

    # 正向查询 按字段:publish
    queryResult=Book.objects.filter(publish__name="人民出版社").values_list("title","price")
    
    # 反向查询 按表名:book
    queryResult=Publish.objects.filter(name="人民出版社").values_list("book__title","book__price")

# 练习2: 查询egon出过的所有书籍的名字(多对多)

    # 正向查询 按字段:authors:
    queryResult=Book.objects.filter(authors__name="yuan").values_list("title")
    
    # 反向查询 按表名:book
    queryResult=Author.objects.filter(name="yuan").values_list("book__title","book__price")

# 练习3: 查询人民出版社出版过的所有书籍的名字以及作者的姓名

    # 正向查询
    queryResult=Book.objects.filter(publish__name="人民出版社").values_list("title","authors__name")
    
    # 反向查询
    queryResult=Publish.objects.filter(name="人民出版社").values_list("book__title","book__authors__age","book__authors__name")

# 练习4: 手机号以151开头的作者出版过的所有书籍名称以及出版社名称

    queryResult=Book.objects.filter(authors__authorDetail__telephone__regex="151").values_list("title","publish__name")

# 练习1:  查询人民出版社出版过的所有书籍的名字与价格(一对多)

# 反向查询 不再按表名:book,而是related_name:bookList
    queryResult = Publish.objects.filter(name="人民出版社").values_list("bookList__title", "bookList__price")

6、修改表记录

Book.objects.filter(price=123,title="python").update(title="python123")

7、删除表记录

Book.objects.filter(price=123,title="python").delete()
你也可以一次性删除多个对象。每个 QuerySet 都有一个 delete() 方法,它一次性删除 QuerySet 中所有的对象。

例如,下面的代码将删除 pub_date 是2005年的 Entry 对象:
Entry.objects.filter(pub_date__year=2005).delete()

要牢记这一点:无论在什么情况下,QuerySet 中的 delete() 方法都只使用一条 SQL 语句一次性删除所有对象,而并不是分别删除每个对象。如果你想使用在 model 中自定义的 delete() 方法,就要自行调用每个对象的delete 方法。(例如,遍历 QuerySet,在每个对象上调用 delete()方法),而不是使用 QuerySet 中的delete()方法。


在 Django 删除对象时,会模仿 SQL 约束 ON DELETE CASCADE 的行为,换句话说,删除一个对象时也会删除与它相关联的外键对象。
例如:
b = Blog.objects.get(pk=1)
# This will delete the Blog and all of its Entry objects.
b.delete()





Django之MTV

标签:url django views

原文:http://blog.51cto.com/qidian510/2104211

(0)
(0)
   
举报
评论 一句话评论(0
0条  
登录后才能评论!
© 2014 bubuko.com 版权所有 鲁ICP备09046678号-4
打开技术之扣,分享程序人生!
             

鲁公网安备 37021202000002号