继续Django

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 环境准备 1、    创建一个Django后,Django的目录: │ manage.py │ ├─Django_s1 │ settings.py │ urls.py │ wsgi.

环境准备

1、    创建一个Django后,Django的目录:

│  manage.py
│
├─Django_s1
│      settings.py
│      urls.py
│      wsgi.py
│      __init__.py
│
│  templates

创建app,通过命令:

python manage.py startapp app01 

创建app之后的目录结构如下:

│  manage.py
│
├─app01
│  │  admin.py
│  │  apps.py
│  │  models.py
│  │  tests.py
│  │  views.py
│  │  __init__.py
│  │
│  └─migrations
│          __init__.py
│
├─Django_s1
│  │  settings.py
│  │  urls.py
│  │  wsgi.py
│  │  __init__.py
│  │
│
└─templates

2、    创建一个项目之后首先需要做的配置

Django_s1目录下settings.py文件中需要做如下配置:

  • 找到MIDDLEWARE部分,将第四行内容注释掉:

'django.middleware.csrf.CsrfViewMiddleware',

  • 找到TEMPLATES部分,如果没有如下代码,则需要添加:

'DIRS': [os.path.join(BASE_DIR, 'templates')]

  • 文件的最后添加静态文件目录,需要注意的是这里是一个元组没所以后面的逗号必须添加
STATICFILES_DIRS=(
    os.path.join(BASE_DIR,"static"),
)

同时需要创建一个名字为static的文件夹,用于存放静态文件

3、    到此为止基本的配置就已经完成,最后的目录结构如下:

│  manage.py
│
├─app01
│  │  admin.py
│  │  apps.py
│  │  models.py
│  │  tests.py
│  │  views.py
│  │  __init__.py
│  │
│  └─migrations
│          __init__.py
│
├─Django_s1
│  │  settings.py
│  │  urls.py
│  │  wsgi.py
│  │  __init__.py
│
│
├─static
└─templates

4、    创建一个测试页面,验证:

  • 主要的业务代码是放在app01目录下view.py文件中,先在view.py中写如下测试代码:
from django.shortcuts import HttpResponse
def index(request):
    return HttpResponse("index")
  • 同时在url.py中添加上对应关系:
from app01 import views

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

登录http://127.0.0.1:8000/index/

5、    写一个简单的登录页面

 

这里我们需要记住:

templates目录中放的是html文件

static中放的是静态文件即css,以及js文件

views.py中写业务代码

urls.py中写路由关系

 

首先在templates里写login.html,代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/login/" method="post">
    <p>
        <input type="text" name="user" placeholder="用户名">
    </p>
    <p>
        <input type="password" name="pwd" placeholder="密码">
    </p>
    <input type="submit" value="提交">
</form>
</body>
</html>

在views,添加如下代码:

def login(request):
    if request.method=="GET":
        return render(request,"login.html")
    elif request.method == "POST":
        u = request.POST.get("user")
        p = request.POST.get("pwd")
        if u == "zhaofan" and p == "123":
            return redirect('/index/')
        else:
            return render(request,"login.html")
    else:
        return redirect('/index/')

在urls路由关系里添加如下代码,黄色背景部分:

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^index/', views.index),
    url(r'^login/', views.login),
]

这样通过浏览器访问效果如下:

关于获取数据和文件上传

实现的代码如下:

1、    在views.py里写如下函数

def login(request):
    if request.method=="GET":
        return render(request,"login.html")
    elif request.method == "POST":
        # v = request.POST.get("gender")
        # print(v)
        # f = request.POST.getlist("city")
        # print(f)
        # file = request.POST.get("upload")
        # print(file)
        obj = request.FILES.get("upload")
        print(obj,type(obj),obj.name)
        import os
        file_path = os.path.join("upload_dir",obj.name)
        f = open(file_path,mode="wb")
        for i in obj.chunks():
            f.write(i)
        f.close()
        return render(request, "login.html")
    else:
        return redirect('/index/')

2、    login.html文件中代码如下;

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/login/" method="post" enctype="multipart/form-data">
    <p>
        <input type="text" name="user" placeholder="用户名">
    </p>
    <p>
        <input type="password" name="pwd" placeholder="密码">
    </p>
    <p>
        男:<input type="radio" name="gender" value="1">
        女:<input type="radio"  name="gender" value="2">
    </p>
    <p>
        乒乓球:<input type="checkbox" name = "favor" value="1">
        篮球:<input type="checkbox" name = "favor" value="2">
        羽毛球:<input type="checkbox" name = "favor" value="3">
    </p>
    <p>
        <select name="city" multiple>
            <option value="sh">上海</option>
            <option value="bj">北京</option>
            <option value="tj">天津</option>
        </select>
    </p>
    <p>
        <input type="file" name="upload">
    </p>
    <input type="submit" value="提交">
</form>
</body>
</html>

3、    关于上述代码中知识点的总结:

  • 当获取单个值的时候类似单选框,可以给标签设置name属性,然后通过类似request.POST.get("gender")方式获取相应的值即:

request.POST.get("标签name属性值")

  • 当获取多个值的时候类似复选框以及可以多选的select的时候,通过request.POST.getlist("city")的方式获取相应的内容,这样得到的是一个列表,即:

request.POST.getlist("标签name属性值")

  • 当时获取上传文件的时候

首先form表单中应该有如下属性:enctype="multipart/form-data"

然后在views.py中通过obj = request.FILES.get("upload")获取文件的一个对象,通过打印可以看出这个对象的详细内容为:<class 'django.core.files.uploadedfile.InMemoryUploadedFile'>即:

request.FILES.get("标签name属性值")

最后通过如下方式循环将文件接收:

        import os
        file_path = os.path.join("upload_dir",obj.name)
        f = open(file_path,mode="wb")
        for i in obj.chunks():
            f.write(i)
        f.close()

这样最后所有的上传文件都会放在upload_dir目录下,当然这个目录需要自己提前创建

关于FBV和CBV

1、    FBV

FBV对应的是function base view

urls.py

index--->函数名

views.py

def 函数(request)

2、    CBV

CBV对应的是class base view

3、    之前写的都是FBV的方式多点,下面通过一个CBV的例子来理解CBV

  • 首先先写一个home.html文件,代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/home/" method="post">
    <input type="text" name="user">
    <input type="submit">
</form>
</body>
</html>
  • views.py中写如下代码:
from django.views import View
# 这里Home需要继承View
class Home(View):
    def get(self,request):
        print(request.method)
        return render(request,"home.html")
    def post(self,request):
        print(request.method)
        return render(request, "home.html")
  • urls.py中写如下代码高亮部分:
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^index/', views.index),
    url(r'^login/', views.login),
    url(r'^home/', views.Home.as_view()),

]
  • 效果如下

当访问页面内容时:

查看django打印的日志可以看出都是的get请求:

当点击提交的时候:查看django的日志可以看出是post请求;

4、    关于CBV,django在内部是如何实现的?

 分析:

当访问页面的时候:头部中请求的方法是GET方式:

当点击提交的时候:头部中的请求的方法是POST方式:

其实当发送请求的时候,是将Request URL以及Request Method同时传递给django,先匹配url,然后去找对应的类,然后找相应的方法,也就是post或者get等,这里判断是post还是get是通过反射实现的。

查看view类里面有一个函数:dispatch函数

    def dispatch(self, request, *args, **kwargs):
        # Try to dispatch to the right method; if a method doesn't exist,
        # defer to the error handler. Also defer to the error handler if the
        # request method isn't on the approved list.
        if request.method.lower() in self.http_method_names:
            handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
        else:
            handler = self.http_method_not_allowed
        return handler(request, *args, **kwargs)

从函数可以看出是dispatch先做了一个反射的功能

所以这个请求的过程是:请求--->dispatch--->get/post

将views.py中的代码更改为如下:

 

from django.views import View
# 这里Home需要继承View
class Home(View):
    # 这样这里就相当于一个装饰器的功能,可以自己定制化内容
    def dispatch(self, request, *args, **kwargs):
        # 调用父类中dispatch方法
        print("before")
        result = super(Home, self).dispatch(request,*args,**kwargs)
        print("after")
        return result
    def get(self,request):
        print(request.method)
        return render(request,"home.html")
    def post(self,request):
        print(request.method)
        return render(request, "home.html")

这样从效果就可以看出当再次访问home页面的时候,每次都需要打印before以及after

5、    模板语言中字典的循环

views.py中写如下代码:

USER_DICT = {
    "k1":"root1",
    "k2":"root2",
    "k3":"root3",
    "k4":"root4",
    "k5":"root5",
}

def index(request):
    return render(request,"index.html",{"user_dict":USER_DICT})

创建一个index.html文件,代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <ul>
        {% for k,row in user_dict.items  %}
            <li>{{ k }}-{{ row }}</li>
        {% endfor %}
    </ul>
</body>
</html>

按照上面的循环方式结果如下:

同样的字典循环包含以下几种方式:

user_dict.items ---- 这样循环row为(k,value)

user_dict.values ---- 这样循环row为value值

user_dict ----这样循环的话row为k值

关于URL路由系统

1、    实现一个点击查看详情的例子(方法一)

views.py中的代码如下;

USER_DICT = {
    "k1":{"name":"root1","email":"root1@qq.com"},
    "k2":{"name":"root2","email":"root2@qq.com"},
    "k3":{"name":"root3","email":"root3@qq.com"},
    "k4":{"name":"root4","email":"root4@qq.com"},

}

def index(request):
    return render(request,"index.html",{"user_dict":USER_DICT})

def detail(request):
    nid = request.GET.get("nid")
    detail_info = USER_DICT[nid]
    return render(request,"detail.html",{"detail_info":detail_info})

index.html文件中的代码如下;

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <ul>
        {% for k,row in user_dict.items  %}
            <li><a target="_blank" href="/detail/?nid={{ k }}">{{ row.name }}</a></li>
        {% endfor %}
    </ul>
</body>
</html>

detail.html代码为如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>详细信息</h1>
    <h6>用户名:{{ detail_info.name }}</h6>
    <h6>邮箱:{{ detail_info.email }}</h6>
</body>
</html>

urls.py中写如下代码高亮部分:

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^index/', views.index),
    url(r'^login/', views.login),
    url(r'^home/', views.Home.as_view()),
    url(r'^detail/', views.detail),

]

实现效果为当打开index主页的时候显示:

 

 

点击某个选项,则可以显示详细信息

2、    实现一个点击查看详情的例子(方法二)

urls.py中的代码如下高亮部分;

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^index/', views.index),
    url(r'^login/', views.login),
    url(r'^home/', views.Home.as_view()),
    #url(r'^detail/', views.detail),
    url(r'^detail-(\d+).html', views.detail),

]

views.py中的代码如下:

USER_DICT = {
    "1":{"name":"root1","email":"root1@qq.com"},
    "2":{"name":"root2","email":"root2@qq.com"},
    "3":{"name":"root3","email":"root3@qq.com"},
    "4":{"name":"root4","email":"root4@qq.com"},

}

def index(request):
    return render(request,"index.html",{"user_dict":USER_DICT})
def detail(request,nid):
    # return HttpResponse(nid)
    detail_info = USER_DICT[nid]
    return render(request,"detail.html",{"detail_info":detail_info})

index.html中的代码为:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <ul>
        {% for k,row in user_dict.items  %}
            <li><a target="_blank" href="/detail-{{ k }}.html">{{ row.name }}</a></li>
        {% endfor %}
    </ul>
</body>
</html>

detail.html中代码不变

最终的效果,点击详细页面之后,地址变为/detail-2.html而不是之前的/detail?nid-2.html:

3、    针对上述的例子,我们将urls.py进行修改:

 

将url(r'^detail-(\d+).html', views.detail),修改为:

url(r'^detail-(\d+)-(\d+).html', views.detail),

这样就存在两个正则,这样在views.py中获取到的时候也需要两个参数,def detail(request,nid,uid),并且这两个参数和顺序有关,第一个参数就是匹配的第一个正则,第二个匹配第二个正则,这样就会有个弊端,一旦调用函数的时候参数传递错误,那个真个函数里设计这两个参数的计算都会出现问题。

所以我们通常用如下方法:

url(r'^detail-(?P<nid>\d+)-(?P<uid>\d+).html', views.detail),

这样就相当于分组,这样就不会应该顺序问题而影响结果

其实在views.py中有一个终极的方法:

def detail(*args,**kwargs),这样当多个参数的就会传递到*args里,当传递字典类型的参数的时候就会传递到**kwargs

4、    name

 

name是对URL路由关系进行命名,以后可以根据此名称生成自己想要的URL

  • url(r'^sdfffddddd/', views.index,name="i1"),
  • url(r'^sdfffddddd/(\d+)/(\d+)/', views.index,name="i2"),
  • url(r'^sdfffddddd/(?P<nid>\d+)/(?P<uid>\d+)/', views.index,name="i3"),

注意:

获取当前URL

request.path_info

 

如果def func(request,*args,**kwargs)

from django.urls impore reverse

 

url1 = reverse("i1")  ----这样就会生成/sdfffddddd/

url2 = reverse("i2",args=(1,2,)) ---生成/1/2/

url3 = reverse("i3",kwargs={"pid":1, "uid":9}) ---生成/1/9

在模板语言中:

{% url "i1" %}    ---生成/sdfffddddd/

{% url "i2" 1 2 %}  --生成/1/2/

{% url "i3" pid=1 uid=3 %} ---生成/1/3/

5、    路由分发

当有 多个app的时候

当请求来的时候先到项目的urls.py里,这里的配置如下:

from django.conf.urls import url,include
from django.contrib import admin

urlpatterns = [
    url(r'^app01/',include("app01.urls")),
    url(r'^app02/',include("app02.urls")),

]

根据不同的app去不同的app下找相应的app级别的urls

这样就实现了路由的分发

Django的ORM

1、    创建类

根据类自动创建数据库表

创建类的位置是在你创建的app目录下有一个models.py,就在这个文件中创建类,写一个简单的类的例子:

class UserInfo(models.Model):
    #django会默认创建一个id列,并且是自增,主键

    #创建用户名列,字符类型,指定长度
    username = models.CharField(max_length=32)
    #c创建密码列,字符类型,指定长度
    password = models.CharField(max_length=64)

创建过之后执行:

python manage.py makemigrations

执行这个命令之后,Django会去找models.py文件

因为我们是在app01下的models.py,所以需要在settings.py中进行指定,找到:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

在最后添加"app01",

这样当执行python manage.py makemigrations,就会找到app01下的models.py从而在app01目录下的migrations目录下生成对应的文件,这个文件就是用于创建数据库表用的,执行过程如下:

D:\python培训\Django_s1>python manage.py makemigrations                                                                                   
Migrations for 'app01':
  app01\migrations\0001_initial.py:
    - Create model UserInfo

D:\python培训\Django_s1>  

然后执行python manage.py migrate,这样就会在数据库中创建表结构,执行过程如下:

D:\python培训\Django_s1>python manage.py migrate                                                                                          
Operations to perform:
  Apply all migrations: admin, app01, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying app01.0001_initial... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying sessions.0001_initial... OK

D:\python培训\Django_s1>  

因为Django默认使用的是sqlite数据库库,所以这个时候会在项目目录下生成一个db.sqlite3的文件,如果想要查看需要第三方程序查看,如果想要用mysql数据库,则需要更改配置。

更改配置如下:

找打settings.py中的如下内容,并注释:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

添加如下内容:并配置自己的数据库信息

DATABASES = {
    'default': {
    'ENGINE': 'django.db.backends.mysql',
    'NAME':'dbname',
    'USER': 'root',
    'PASSWORD': 'xxx',
    'HOST': '',
    'PORT': '',
    }
}

由于Django内部连接mysql用的是MySQLdb模块,而python3中已经没有了这个模块,所以需要使用pymysql来代替MySQLdb,配置如下:

在与项目同名的文件目录下的__init__.py文件中添加如下内容:

import pymysql
pymysql.install_as_MySQLdb()

这样重新执行python manage.py migrate即可

查看数据你会看到如下表:

其中只有一个表app01_userinfo是你自己通过类创建的其他都是django自己创建的,查看app01_userinfo表结构信息:

2、    添加数据

方法一:(推荐这种方法)

models.UserInfo.objects.create(username = "root", password = "123",)

首先在app01下的urls.py中添加如下内容:

url(r'^app02/',include("app02.urls")),

然后在views.py中添加如下内容:

from app01 import models
def orm(request):
    models.UserInfo.objects.create(
        username = "root",
        password = "123",
    )
    return HttpResponse("orm is ok")

然后通过浏览器访问http://127.0.0.1:8000/app01/orm/

这样就在数据库里添加了一条数据数据

方法二:

  • obj = models.UserInfo(username="dean",password = "123456")

 obj.save()

然后通过浏览器访问http://127.0.0.1:8000/app01/orm/

这样就在数据库里添加了一条数据数据

方法三:

dic={"username":"erric","password":"555"}、models.UserInfo.objects.create(**dic)

return HttpResponse("orm is ok")

然后通过浏览器访问http://127.0.0.1:8000/app01/orm/

这样就在数据库里添加了一条数据数据

 

3、    查询数据

 

查询所有数据

result = models.UserInfo.objects.all()

这样得到的result通过打印时如下:

<QuerySet [<UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>]>

这个QuerySet是Django创建的一种类似列表的格式,这里面每个元素就是数据库每行的一个对象,这样我们就能通过循环获取每行的数据,方法如下:

    result = models.UserInfo.objects.all()
    print(result)
    for row_obj in result:
        print(row_obj.id,row_obj.username,row_obj.password)
    return HttpResponse("orm is ok")

根据条件 查询数据

result =models.UserInfo.objects.filter(username="root")

这里的filter就相当于sql语句中的where条件

4、    删除数据

models.UserInfo.objects.delete() 删除所有数据

models.UserInfo.objects.filter(id=2).delete() 通过条件删除

 

5、    更新数据

models.UserInfo.objects.all().update(password=222)

上面是将所有的的密码都更改,

如果想要根据条件更改则可以:

models.UserInfo.objects.filter(id=2).update(password=888)

 

 

 

所有的努力都值得期许,每一份梦想都应该灌溉!
相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
3月前
|
SQL 前端开发 API
Django 系列
【8月更文挑战第20天】
28 1
|
4月前
|
关系型数据库 MySQL 数据库
django初学
【7月更文挑战第3天】1. 安装Django: `pip install Django` 2. 创建项目: `django-admin startproject HelloWorld` 3. 启动项目: `python manage.py runserver 0.0.0.0:8000` 4. 生成应用: `django-admin startapp TestModel` 5. 配置多数据库(MySQL):
32 1
|
6月前
|
SQL 数据库 数据库管理
深入Django(七)
Django的数据库迁移系统是管理数据库模式变化的关键组件,自动化创建、修改和删除表及字段。它提供版本控制,便于团队协作。通过`makemigrations`生成迁移文件,`migrate`应用到数据库。迁移支持依赖关系和数据迁移功能,允许填充初始数据或执行数据转换。这个系统简化了数据库管理,促进了开发中的数据一致性。
48 5
|
6月前
|
Python
深入Django(三)
本文详细介绍了Django视图(Views)。视图是Django中处理用户请求并返回响应的函数或类,负责应用程序逻辑。文章通过实例展示了如何创建简单视图、使用类视图以及如何与模板配合动态生成HTML内容。此外,还提到了视图处理表单、权限认证和错误处理的功能。总之,Django视图是应用的核心组件,用于处理业务逻辑和用户交互。
29 2
|
6月前
|
SQL 中间件 Linux
深入Django系列
本文是Django入门教程的第一天,简要介绍了Django,一个遵循DRY原则的开源Web框架。核心特性包括ORM、自动URL路由、模板系统、表单处理和中间件支持。随后,文章指导读者如何搭建开发环境:安装Python,创建并激活虚拟环境,使用pip安装Django,创建项目及运行开发服务器。通过这些步骤,读者可以开始他们的第一个Django项目。
27 2
|
6月前
|
前端开发 数据管理 API
深入Django(二)
本文介绍了Django的模型(Models)系统,它是Django框架中处理数据库的核心部分。模型是通过Python类定义的,对应数据库中的表,属性代表表的字段。通过模型,可以方便地操作数据,如创建、查询、更新和删除记录。文中展示了如何创建`Author`和`Post`模型,以及如何使用ORM进行对象操作。此外,还提到了模型的高级特性,如字段选项、字段类型、关系以及自定义方法和属性,这些都是Django高效管理数据的关键。理解模型对于Django应用开发至关重要。
37 1
|
算法 前端开发 网络安全
【Django】Hello,DJango!
这样就在主目录下创建了一个自己的项目以下统称创建的项目路径为根目录(即ppeua_app/)
101 0
|
数据库 数据安全/隐私保护 Python
|
算法 前端开发 程序员
初识Django(一)
什么Django        Django是一个开放源代码的Web应用框架,由Python写成。采用了MVC的框架模式,即模型M,视图V和控制器C。它最初是被开发来用于管理劳伦斯出版集团旗下的一些以新闻内容为主的网站的,即是CMS(内容管理系统)软件。
1600 0
|
Python 前端开发 数据库
第24天,Django之ModelForm
一. 创建一个ModelForm 1.1 使用之前需要导入对应app中的models和Django提交的ModelForm类 from django.forms import ModelForm from app01.
1020 0