【Django】快速入门_基本配置

前提

已安装python3.X

安装完django

创建项目

#在命令行执行
#HelloWorld 项目名称
django-admin startproject HelloWorld

#进入项目
cd HelloWorld

目录说明

|-- HelloWorld
| |-- init.py #空文件,告诉Python这是一个Python的包
| |-- asgi.py #一个 ASGI 兼容的 Web 服务器的入口,以便运行你的项目。
| |-- settings.py #该 Django 项目的设置/配置。
| |-- urls.py #该 Django 项目的 URL 声明; 一份由 Django 驱动的网站"目录"。
| -- wsgi.py-- manage.py #一个 WSGI 兼容的 Web 服务器的入口,以便运行你的项目。

运行项目

#确保已进入HelloWorld目录下

#多种运行项目的方式
python manage.py runserver
# 指定端口
python manage.py runserver 8080
# 任意ip接入
python manage.py runserver 0.0.0.0:8080
# 这里和settings.py的配置ALLOWED_HOSTS = []
# 不一样的地方在于,这个是服务器监听的IP,IP不对无法连接到服务;
# ALLOWED_HOSTS是已经连接到服务,但连接的IP不在ALLOWED_HOSTS范围内就无法正常提供服务

运行完项目访问 127.0.0.1:8000,就能看到一个绿色的小火箭!

视图和URL配置

注意import

HelloWorld 目录新建一个 views.py 文件

#目录:HelloWorld/HelloWorld/views.py

from django.http import HttpResponse
 
def hello(request):
    return HttpResponse("Hello world ! ")

绑定 URL 与视图函数

from django.conf.urls import url
 
from . import views
 
urlpatterns = [
    url(, views.hello),
]

path() 函数

path(route, view, kwargs=None, name=None)
  • route: 字符串,表示 URL 规则,与之匹配的 URL 会执行对应的第二个参数 view。(可用正则表达式)
  • view: 用于执行与正则表达式匹配的 URL 请求。
  • kwargs: 视图使用的字典类型的参数。
  • name: 用来反向获取 URL。

route:

  • 对应端口号后的路径
  • 例如:http://127.0.0.1:8000/hello/,则route = “hello/”

views:

  • from . import views导入的
  • views.hello 对应的是views中的一个函数

kwargs:

  • 少用到,暂不学

模板

为什么需要模板?

在上文views的hello中使用 django.http.HttpResponse() 来输出 "Hello World!",该方式将数据与视图混合在一起,不符合 Django 的 MVC 思想

模板:模板是一个文本,用于分离文档的表现形式和内容。

建立模板

在 HelloWorld 目录底下创建 templates 目录并建立 runoob.html

项目结构

HelloWorld/
|-- HelloWorld
|   |-- __init__.py
|   |-- __init__.pyc
|   |-- settings.py
|   |-- settings.pyc
|   |-- urls.py
|   |-- urls.pyc
|   |-- views.py
|   |-- views.pyc
|   |-- wsgi.py
|   `-- wsgi.pyc
|-- manage.py
`-- templates
    `-- runoob.html

HelloWorld/templates/runoob.html 文件代码

{{ hello }}

修改HelloWorld/settings.py

修改 TEMPLATES 中的 DIRS 为 [os.path.join(BASE_DIR, 'templates')]

  • 注意导入:import os
...
import os
...
TEMPLATES = [
    {
        ...
        'DIRS': [os.path.join(BASE_DIR, 'templates')]
        ...
    },
]
...

修改 views.py

from django.shortcuts import render
 
def runoob(request):
    context          = {}
    context['hello'] = 'Hello World!'
    return render(request, 'runoob.html', context)

#context可换成{"name":views_name}

修改HelloWorld/HelloWorld/urls.py

from django.urls import path
 
from . import views
 
urlpatterns = [
    path('runoob/', views.runoob),
]

模板语法

views中的变量与html中变量“绑定”

view:{"HTML变量名" : "views变量名"}
HTML:{{变量名}}
#html页面中

{{HTML变量名}}

#在views中 return render(request, 'runoob.html', {"HTML变量名" : "views变量名"})

网页导航和页脚

使用子模版继承父模版,减少代码冗余

父模板





base


    

Hello World!

父模板测试

{% block mainbody %}

base template

{% endblock %}

子模板

{%extends "base.html" %}

  • 继承了一个父模板(网页)

父模板的{% block 名称%}{% 名称%}

  • 相当于留空位给子模版新增内容
  • 标签是可以被继承者们替换掉的部分
{%extends "base.html" %}
 
{% block mainbody %}

继承了 base.html 文件

{% endblock %}

模型

参考

Django 模型使用自带的 ORM。

  • 对象关系映射(Object Relational Mapping,简称 ORM )用于实现面向对象编程语言里不同类型系统的数据之间的转换。
image.png
# 安装 mysql 驱动
pip install pymysql

在数据库软件中新建数据库

-- runoob 数据库名
create database runoob default charset=utf8;  

修改 HelloWorld/HelloWorld/settings.py 中的DATABASES

DATABASES = { 
    'default': 
    { 
        'ENGINE': 'django.db.backends.mysql',    # 数据库引擎
        'NAME': 'runoob', # 数据库名称
        'HOST': '127.0.0.1', # 数据库地址,本机 ip 地址 127.0.0.1 
        'PORT': 3306, # 端口 
        'USER': 'root',  # 数据库用户名
        'PASSWORD': '123456', # 数据库密码
    }  
}

告诉 Django 使用 pymysql 模块连接 mysql 数据库

# 在与 settings.py 同级目录下的 __init__.py 中引入模块和进行配置 
import pymysql
pymysql.install_as_MySQLdb()

定义模型

Django 规定,如果要使用模型,必须要创建一个 app。

#命令行中输入
# TestModel与manage.py在同级目录下
django-admin.py startapp TestModel

创建表

修改 TestModel/models.py 文件

# models.py
from django.db import models
 
class Test(models.Model):
    name = models.CharField(max_length=20)

类名代表了数据库表名(Test)

类里面的字段代表数据表中的字段(name)

数据类型则由CharField(相当于varchar)、DateField(相当于datetime)

max_length 参数限定长度。

告诉django我们安装的app

在 settings.py 中找到INSTALLED_APPS

  • setting.py在HelloWorld目录下
INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'TestModel',               # 添加此项
)

命令行中运行

python manage.py migrate   # 创建表结构

python manage.py makemigrations TestModel  # 让 Django 知道我们在我们的模型有一些变更
python manage.py migrate TestModel   # 创建表结构
#如果代码有报异常,继续往下翻。

第二行代码执行后

image.png

第三行代码执行后

image.png

该表结构

Django 会自动添加一个 id 作为主键。

image.png

异常

django.db.utils.OperationalError:(1045,"Access denied for user 'root'@'localhost'

  • 确保用户名和密码正确后再试一次
    • 可以用命令行测试数据库连接
    • 开启服务:net start 服务名(例如:mysql5.7)
    • mysql -h 主机名(ip) -u 用户名 -P 端口 -p

其他解决方案

数据库操作

HelloWorld 目录中添加 testdb.py 文件,并修改 urls.py

#urls.py
from django.urls import path
 
from . import views,testdb
 
urlpatterns = [
    path('runoob/', views.runoob),
    path('testdb/', testdb.testdb),
]
添加数据
from django.http import HttpResponse
 
from TestModel.models import Test
 
# 数据库操作
def testdb(request):
    test1 = Test(name='runoob')
    test1.save()
    return HttpResponse("

数据添加成功!

")

启动服务器并访问

python manage.py runserver #启动服务器

#访问 http://127.0.0.1:8000/testdb/
#看到页面输出:数据添加成功

查看数据库

image.png
获取数据、删除、修改

参考

#获取
# 通过objects这个模型管理器的all()获得所有数据行,相当于SQL中的SELECT * FROM
list = Test.objects.all()

# filter相当于SQL中的WHERE,可设置条件过滤结果
response2 = Test.objects.filter(id=1) 

# 获取单个对象
response3 = Test.objects.get(id=1) 

# 限制返回的数据 相当于 SQL 中的 OFFSET 0 LIMIT 2;(分页)
Test.objects.order_by('name')[0:2]

#数据排序
Test.objects.order_by("id")

# 上面的方法可以连锁使用
Test.objects.filter(name="runoob").order_by("id")
#修改
#save() 或 update():
# 修改其中一个id=1的name字段,再save,相当于SQL中的UPDATE
test1 = Test.objects.get(id=1)
test1.name = 'Google'
test1.save()

# 另外一种方式
Test.objects.filter(id=1).update(name='Google')

# 修改所有的列
Test.objects.all().update(name='Google')
#删除
# 删除id=1的数据
test1 = Test.objects.get(id=1)
test1.delete()

# 另外一种方式
Test.objects.filter(id=1).delete()

# 删除所有数据
Test.objects.all().delete()

异常

删除数据库表后无法更新

问题:修改模型后无法更新数据库表结构,删除后再执行命令也不行。参考

解决:

  1. 删除app/migrations/目录下 “_pycache_” 文件

  2. 删除app下面目录migrations下面除了init.py其他的所有文件

  3. 删除对应数据库中django_migrations表中app名称所在的列

    (或者delete from django_migrations where app=‘yourappname’;),解决无法生成表

表单

HTML表单是网站交互性的经典方式。

HTTP协议以"请求-回复"的方式工作。

  • 客户发送请求时,可以在请求中附加数据。
  • 服务器通过解析请求,就可以获得客户传来的数据,并根据URL来提供特定的服务。

GET

创建一个 search.py 文件,用于接收用户的请求

#/HelloWorld/HelloWorld/search.py 文件

from django.http import HttpResponse
from django.shortcuts import render

#表单
def search_form(request):
    return render(request,'search_form.html')

#接收请求数据
def search(request):
    request.encoding='utf-8'
    if('q' in request.GET and request.GET['q']):
        message = '您搜索的内容为:' + request.GET['q']
    else:
        message = '您提交了空表单'
    return HttpResponse(message)

模板目录 templates 中添加 search_form.html 表单

#/HelloWorld/templates/search_form.html 文件




    
    form_test


    

urls.py 规则 添加以下代码

使用url能匹配正则表达式(path好像不行)

...
from django.conf.urls import url

urlpatterns = [
    ...,
    url(r'^search-form/$',search.search_form),
    url(r'^search/$',search.search)
]

访问 http://127.0.0.1:8000/search-form/,搜索后提交即可看到效果

GET请求 视图显示和请求处理分成两个函数处理。

POST

提交数据时更常用POST方法。

  • 一个URL和处理函数,同时显示视图和处理请求。

Request对象

表单form通过HTTP POST方法提交请求,但是表单中可以没有数据。

因此,不能使用语句if request.POST来判断是否使用HTTP POST方法;

应该使用if request.method == "POST"

参考1

参考2

参考3

路由

Django不会匹配域名和协议

举例:

请求:访问http://127.0.0.1:8000/polls/34/

Django项目到urls中顺序进行正则匹配/polls/34/,匹配到polls/,就切掉文本"polls/",剩余文本"34/"继续进行匹配

  • path('polls/',include('polls.urls'))
  • path('/', views.detail, name='detail')

匹配到了views.detail

得到参数question_id=34 匹配生成。

  • 使用尖括号“捕获”这部分 URL,且以关键字参数的形式发送给视图函数。
  • 上述字符串的 :question_id> 部分定义了将被用于区分匹配模式的变量名
  • int: 则是一个转换器决定了应该以什么变量类型匹配这部分的 URL 路径。

路由简单的来说就是根据用户请求的 URL 链接来判断对应的处理程序,并返回处理结果,

  • URL 与 Django 的视图建立映射关系。

Django 路由在 urls.py 配置,urls.py 中的每一条配置对应相应的处理方法。

Django 不同版本 urls.py 配置有点不一样

Django1.1.x 版本

url() 方法:普通路径和正则路径均可使用,需要自己手动添加正则首位限制符号。

from django.conf.urls import url # 用 url 需要引入 

urlpatterns = [ 
    url(r'^admin/$', admin.site.urls), 
    url(r'^index/$', views.index), # 普通路径 
    url(r'^articles/([0-9]{4})/$', views.articles), # 正则路径 
]

Django 2.2.x 之后

  • path:用于普通路径,不需要自己手动添加正则首位限制符号,底层已经添加。
  • re_path:用于正则路径,需要自己手动添加正则首位限制符号。
from django.urls import re_path # 用re_path 需要引入 
urlpatterns = [ 
    path('admin/', admin.site.urls), 
    path('index/', views.index), # 普通路径 
    re_path(r'^articles/([0-9]{4})/$', views.articles), # 正则路径 
]

总结:Django1.1.x 版本中的 url 和 Django 2.2.x 版本中的 re_path 用法相同。

分组

参考

正则还有分组的概念,但是在Django中把分组分为两种:

  • 无名分组
  • 有名分组

无名分组

无名分组:普通的正则匹配中加上()

作用:在后端的views上,会得到一个分组的参数

  • 访问views.login函数(下方)的参数除了request,还需要添加一个参数(名字随意)
  • 要设置几个参数就要多几个分组

以下代码访问:login/2222,那么xxx的值为2222

#urls.py
urlpatterns = [
 url(r'^login/([0-9]{4})$',views.login),
]

#views.py
def login(request,xxx):
    print(xxx)

举例参考

#search2.py
def divede_group_year(request,year):
    return HttpResponse('您的选择是:%s' % year)
def divede_group_month(request,year,month):
    return HttpResponse('选择的月份是:%s-%s' %(year,month))

#urls.py
from django.urls import path,re_path
...

urlpatterns = [
    ...,
    # 记得添加结束标签 $
    re_path(r'^divede-group/([0-9]{4})/$',search2.divede_group_year),
    re_path(r'^divede-group/([0-9]{4})/([0-9]{2})/$',search2.divede_group_month)
]
image.png
image.png

有名分组

有名分组: 有名分组其实就是在无名的分组的基础上加上了名字

语法为:(?P<名字> 正则表达式)

#urls.py
...,

urlpatterns = [
    ...,
 url(r'^login/(?P[0-9]{4})$',views.login),
]

#views.py
...,
def login(request,year):
     print(year)

举例

#search2.py
from django.http import HttpResponse
def divede_group_name(request,name):
    return HttpResponse('有名分组:%s' %(name))

#urls.py
from . import search2
re_path(r'^divede-group/(?P[a-z]{4})/$',search2.divede_group_name)
image.png

视图函数的参数name 要和有名参数的名字name一致,否则会报错!

注意:官方规定,有名分组和无名分组不能一起使用!

路由分发(include)

问题:

  • 项目里多个app目录共用一个 urls 容易造成混淆
  • 后期维护不方便

解决:

  • 使用路由分发(include),让每个app目录都单独拥有自己的 urls。

步骤:

  • 1、在每个 app 目录里都创建一个 urls.py 文件。
  • 2、在项目名称目录下的 urls 文件里,统一将路径分发给各个 app 目录。
举例:

有两个app,都有index.html页面

  • 如果在项目的urls中配置,则会造成混淆
  • 且如果有太多的url,则维护十分难

所以应该把各种的url分给各自去管理

#路由 未分发
#项目主目录下的urls.py
urlpatterns = [
    url(r'^app-one/index/$',views.index),
    url(r'^app-two/index/$',views.index)
]

新建两个app

# 语法:python manage.py startapp 
# 命令行中运行
python manage.py startapp app01
python manage.py startapp app02

app1目录下

1.views文件

from django.http import HttpResponse

def index(request):
    return HttpResponse('app01的index页面!')

2.新建urls.py文件

from . import views
from django.conf.urls import url #没有引入会报错:NameError: name 'url' is not defined django
urlpatterns = [
    url(r'^index/$',views.index)
]

app2目录下

1.views文件

from django.http import HttpResponse

def index(request):
    return HttpResponse('app2:index!')

2.新建urls.py文件

from . import views
from django.conf.urls import url

urlpatterns = [
    url(r'^index/$',views.index)
]

项目主目录下的urls.py

urlpatterns = [
    url(r'^app-one/',include('app01.urls')),
    url(r'^app-two/',include('app02.urls'))
]

访问

注意访问路径:

  • app-one/index/
  • 对照上面的urls.py文件,就能理解路由转发了!

app01

运行项目:python manage.py runserver

image.png

app02

image.png

反向解析

目的:解耦

  • 路由层的 url 发生变化,就需要去更改对应的视图层和模板层的 url,不便维护

反向解析

  • 当路由层 url 发生改变,在视图层和模板层动态反向解析出更改后的 url,免去修改的操作。
  • 一般用在模板中的超链接及视图中的重定向

问题举例

#urls.py 中的一条url
...
url(r'^login/$',views.login)
...
#html页面中的提交表单
...

当更改路由中的url时,需要在html页面也做相应的更改!

解耦目的:只更改路由中的url,html中会自动做出更改,我们无需去改变!

反向解析

方法:给路由器起别名

应用:

举例参考

1.普通路径:name="路由别名

重定向:

  • redirect(reverse("login"))

超链接:

2.正则路径:无名分组

re_path(r"^login/([0-9]{2})/$", views.login, name="login")

重定向:

  • reverse("路由别名",args=(符合正则匹配的参数,))
    • redirect(reverse("login",args=(10,)))

超链接:

  • {% url "路由别名" 符合正则匹配的参数 %}
    • {% url 'login' 10 %}

3.正则路径:有名分组

re_path(r"^login/(?P[0-9]{4})/$", views.login, name="login")

重定向:

  • reverse("路由别名",kwargs={"分组名":符合正则匹配的参数})
    • redirect(reverse("login",kwargs={"year":3333}))

超链接:

  • {% url "路由别名" 分组名=符合正则匹配的参数 %}
    • {% url 'login' year=3333 %}

命名空间

命名空间(英语:Namespace)是表示标识符可见范围

一个标识符可在多个命名空间中定义,它在不同命名空间中的含义是互不相干的。

一个新的命名空间中可定义任何标识符,它们不会与任何重复的标识符发生冲突,因为重复的定义都处于其它命名空间中。

存在问题:路由别名 name 没有作用域,Django 在反向解析 URL 时,会在项目全局顺序搜索,当查找到第一个路由别名 name 指定 URL 时,立即返回。当在不同的 app 目录下的urls 中定义相同的路由别名 name 时,可能会导致 URL 反向解析错误。

解决:使用命名空间。

普通路径

方式一:

#主目录下的urls
urlpatterns = [
    path('admin/', admin.site.urls),
    path('polls/',include('polls.urls'))
]
# polls中的urls.py
from django.urls import path
from . import views

app_name = 'polls' #命名空间
urlpatterns = [
    ...
    # ex: /polls/5/
    path('/', views.detail, name='detail'),
    ...
]
  • {{ question.question_text }}
  • 方式二:

    定义命名空间(include 里面是一个元组)

    include(("app名称:urls","app名称"))
    

    实例

    path("app01/", include(("app01.urls","app01"))) 
    path("app01/", include(("app02.urls","app02")))
    

    起别名

    path("login/", views.login, name="login")
    

    调用

    #重定向
    redirect(reverse("app01:login")
             
    #超链接
    {% url "app名称:路由别名" %}
    

    视图

    每个视图必须要做的只有两件事:

    • 返回一个包含被请求页面内容的 HttpResponse 对象
    • 或者抛出一个异常,比如 Http404

    基于类的视图

    Admin 管理工具

    介绍

    Django 提供了基于 web 的管理工具。

    Django 自动管理工具是 django.contrib 的一部分。

    在项目的 settings.py 中的 INSTALLED_APPS 可以看到

    INSTALLED_APPS = (
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
    )
    

    django.contrib是一套庞大的功能集,它是Django基本代码的组成部分。

    激活管理工具

    在生成项目时会在 urls.py 中自动设置好,我们只需去掉注释即可。

    配置如下

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

    使用管理工具

    创建超级用户

    # python manage.py createsuperuser
    Username (leave blank to use 'root'): admin
    Email address: 
    Password:admin
    Password (again):
    Superuser created successfully.
    
    1. 创建模型(model)
    2. 修改admin.py
    3. 告知Django模型有更改
    4. 创建表

    之前在 TestModel 中已经创建了模型 Test 。修改 TestModel/admin.py:

    from django.contrib import admin
    from TestModel.models import Test
     
    # Register your models here.
    admin.site.register(Test)
    

    复杂模型

    TestModel/models.py 中增加一个更复杂的数据模型

    from django.db import models
    
    # Create your models here.
    class Test(models.Model):
        name = models.CharField(max_length=20)
    
    class Contact(models.Model):
        name = models.CharField(max_length=20)
        age = models.IntegerField(default=0)
        email = models.EmailField()
        def __unicode__(self):
            return self.name
    
    class Tag(models.Model):
        concate = models.ForeignKey(Contact,on_delete=models.CASCADE)
        name = models.CharField(max_length=50)
        def __unicode__(self):
            return self.name
    

    TestModel/admin.py中修改

    from django.contrib import admin
    from TestModel.models import Test,Contact,Tag
    
    # Register your models here.
    admin.site.register([Test,Contact,Tag])
    

    刷新 http://127.0.0.1:8000/admin/ 页面

    image.png

    现在只是有了Concate和Tag模型,在数据库中还没有对应的表

    (Test是文章前面建的)

    image.png

    使用以下命令创建表结构

    python manage.py makemigrations TestModel  # 让 Django 知道我们在我们的模型有一些变更
    python manage.py migrate TestModel   # 创建表结构
    

    第一条命令执行完,多了一个文件

    image.png

    第二条命令执行完,创建了对应的表

    (有关数据库连接请看“模型”)

    image.png

    自定义admin界面

    自定义表单

    1.把Age隐藏起来
    image.png

    修改 TestModel/admin.py:

    from django.contrib import admin
    from TestModel.models import Test,Contact,Tag
    
    # Register your models here.
    class ContactAdmin(admin.ModelAdmin):  #新增代码
        fields = ('name','email')         #新增代码
    
    admin.site.register(Contact,ContactAdmin) #新增代码
    admin.site.register([Test,Tag])          #删除",Contact"
    

    代码说明

    定义了一个 ContactAdmin 类,用以说明管理页面的显示格式。

    • fields 属性定义了要显示的字段
    • 该类对应的是 Contact 数据模型,我们在注册的时候,需要将它们一起注册

    刷新后显示效果如下

    image.png
    2.将输入栏分块,每个栏也可以定义自己的格式。

    注意字母拼写不要错误!!!

    from django.contrib import admin
    from TestModel.models import Test,Contact,Tag
     
    # Register your models here.
    class ContactAdmin(admin.ModelAdmin):
        fieldsets = (
            ['Main',{
                'fields':('name','email'),
            }],
            ['Advance',{
                'classes': ('collapse',), # CSS
                'fields': ('age',),
            }]
        )
    
    admin.site.register(Contact, ContactAdmin)
    admin.site.register([Test, Tag])
    

    刷新页面

    image.png

    点击“Show”

    image.png

    说明

    上面的栏目分为了 Main 和 Advance 两部分。

    classes 说明它所在的部分的 CSS 格式。这里让 Advance 部分隐藏

    内联(Inline)显示

    上面的 Contact 是 Tag 的外部键,所以有外部参考的关系。

    问题:在默认的页面显示中,将两者分离开来,无法体现出两者的从属关系。

    解决:可以使用内联显示,让 Tag 附加在 Contact 的编辑页面上显示。

    修改TestModel/admin.py

    from django.contrib import admin
    from TestModel.models import Test,Contact,Tag
    
    # Register your models here.
    class TagInline(admin.TabularInline): #新增代码
        model = Tag                     #新增代码
    
    class ContactAdmin(admin.ModelAdmin):
        inlines = [TagInline] #Inline   #修改代码
        fieldsets = (
        ['Main',{
            'fields':('name','email'),
        }],
        ['Advance',{
            'classes':('cpllapse',), #CSS
            'fields':('age',),
        }]
    )
            
    
    admin.site.register(Contact,ContactAdmin)
    admin.site.register([Test])         #修改代码
    

    刷新显示

    image.png

    列表页的显示

    在 Contact 输入数条记录后,Contact 的列表页看起来如下

    image.png

    目的:在列表中显示更多的栏目

    • 在 ContactAdmin 中增加 list_display 属性
    from django.contrib import admin
    from TestModel.models import Test,Contact,Tag
    
    # Register your models here.
    class TagInline(admin.TabularInline):
        model = Tag
    
    class ContactAdmin(admin.ModelAdmin):
        list_display = ('name','age','email') #新增list_display属性
        inlines = [TagInline] #Inline
        fieldsets = (
        ['Main',{
            'fields':('name','email'),
        }],
        ['Advance',{
            'classes':('cpllapse',), #CSS
            'fields':('age',),
        }]
    )
            
    
    admin.site.register(Contact,ContactAdmin)
    admin.site.register([Test])
    

    刷新显示

    image.png

    app

    一个项目中可以创建很多个app

    app可以用路由分发解决url冲突

    使用命名空间也可以减少模板冲突等等

    应用1

    image.png

    qyvxtest:项目名

    charlist:新建的app

    app可以成为绝对路径的引入,解决的导入模块时的问题

    例如:在一个项目中,新建了一个app,在该app的views中

    from . import models
    
    #异常
    #RuntimeError: Model class chatlist.models.User doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS
    

    在setting中

    INSTALLED_APPS = [
        ...,
        'chatlist',
    ]
    

    则在该app的view中可以

    from . import models
    #或者
    from chatlist import models
    

    你可能感兴趣的:(【Django】快速入门_基本配置)