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

前提

已安裝python3.X

安裝完django

創(chuàng)建項目

#在命令行執(zhí)行
#HelloWorld 項目名稱
django-admin startproject HelloWorld

#進入項目
cd HelloWorld

目錄說明

|-- HelloWorld
| |-- init.py #空文件蛮浑,告訴Python這是一個Python的包
| |-- asgi.py #一個 ASGI 兼容的 Web 服務器的入口,以便運行你的項目。
| |-- settings.py #該 Django 項目的設置/配置盛杰。
| |-- urls.py #該 Django 項目的 URL 聲明; 一份由 Django 驅動的網(wǎng)站"目錄"。
| -- 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 = []
# 不一樣的地方在于吗坚,這個是服務器監(jiān)聽的IP牡彻,IP不對無法連接到服務严就;
# ALLOWED_HOSTS是已經(jīng)連接到服務渐行,但連接的IP不在ALLOWED_HOSTS范圍內(nèi)就無法正常提供服務

運行完項目訪問 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 與視圖函數(shù)

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

path() 函數(shù)

path(route, view, kwargs=None, name=None)
  • route: 字符串豌习,表示 URL 規(guī)則栋艳,與之匹配的 URL 會執(zhí)行對應的第二個參數(shù) view矾屯。(可用正則表達式)
  • view: 用于執(zhí)行與正則表達式匹配的 URL 請求。
  • kwargs: 視圖使用的字典類型的參數(shù)。
  • name: 用來反向獲取 URL僧著。

route:

views:

  • from . import views導入的
  • views.hello 對應的是views中的一個函數(shù)

kwargs:

  • 少用到,暫不學

模板

為什么需要模板?

在上文views的hello中使用 django.http.HttpResponse() 來輸出 "Hello World吮成!"危纫,該方式將數(shù)據(jù)與視圖混合在一起,不符合 Django 的 MVC 思想

模板:模板是一個文本,用于分離文檔的表現(xiàn)形式和內(nèi)容。

建立模板

在 HelloWorld 目錄底下創(chuàng)建 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 文件代碼

<h1>{{ hello }}</h1>

修改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頁面中
<h1>{{HTML變量名}}</h1>

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

網(wǎng)頁導航和頁腳

使用子模版繼承父模版退渗,減少代碼冗余

父模板

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>base</title>
</head>
<body>
    <h1>Hello World!</h1>
    <p>父模板測試</p>
    {% block mainbody %}
       <p>base template</p>
    {% endblock %}
</body>
</html>

子模板

{%extends "base.html" %}

  • 繼承了一個父模板(網(wǎng)頁)

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

  • 相當于留空位給子模版新增內(nèi)容
  • 標簽是可以被繼承者們替換掉的部分
{%extends "base.html" %}
 
{% block mainbody %}
<p>繼承了 base.html 文件</p>
{% endblock %}

模型

參考

Django 模型使用自帶的 ORM稻薇。

  • 對象關系映射(Object Relational Mapping忱屑,簡稱 ORM )用于實現(xiàn)面向對象編程語言里不同類型系統(tǒng)的數(shù)據(jù)之間的轉換从铲。
image.png
# 安裝 mysql 驅動
pip install pymysql

在數(shù)據(jù)庫軟件中新建數(shù)據(jù)庫

-- runoob 數(shù)據(jù)庫名
create database runoob default charset=utf8;  

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

DATABASES = { 
    'default': 
    { 
        'ENGINE': 'django.db.backends.mysql',    # 數(shù)據(jù)庫引擎
        'NAME': 'runoob', # 數(shù)據(jù)庫名稱
        'HOST': '127.0.0.1', # 數(shù)據(jù)庫地址,本機 ip 地址 127.0.0.1 
        'PORT': 3306, # 端口 
        'USER': 'root',  # 數(shù)據(jù)庫用戶名
        'PASSWORD': '123456', # 數(shù)據(jù)庫密碼
    }  
}

告訴 Django 使用 pymysql 模塊連接 mysql 數(shù)據(jù)庫

# 在與 settings.py 同級目錄下的 __init__.py 中引入模塊和進行配置 
import pymysql
pymysql.install_as_MySQLdb()

定義模型

Django 規(guī)定警没,如果要使用模型浅碾,必須要創(chuàng)建一個 app绵载。

#命令行中輸入
# TestModel與manage.py在同級目錄下
django-admin.py startapp TestModel

創(chuàng)建表

修改 TestModel/models.py 文件

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

類名代表了數(shù)據(jù)庫表名(Test)

類里面的字段代表數(shù)據(jù)表中的字段(name)

數(shù)據(jù)類型則由CharField(相當于varchar)懂版、DateField(相當于datetime)

max_length 參數(shù)限定長度。

告訴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   # 創(chuàng)建表結構

python manage.py makemigrations TestModel  # 讓 Django 知道我們在我們的模型有一些變更
python manage.py migrate TestModel   # 創(chuàng)建表結構
#如果代碼有報異常,繼續(xù)往下翻付翁。

第二行代碼執(zhí)行后

image.png

第三行代碼執(zhí)行后

image.png

該表結構

Django 會自動添加一個 id 作為主鍵赫粥。

image.png

異常

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

  • 確保用戶名和密碼正確后再試一次
    • 可以用命令行測試數(shù)據(jù)庫連接
    • 開啟服務:net start 服務名(例如:mysql5.7)
    • mysql -h 主機名(ip) -u 用戶名 -P 端口 -p

其他解決方案

數(shù)據(jù)庫操作

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),
]
添加數(shù)據(jù)
from django.http import HttpResponse
 
from TestModel.models import Test
 
# 數(shù)據(jù)庫操作
def testdb(request):
    test1 = Test(name='runoob')
    test1.save()
    return HttpResponse("<p>數(shù)據(jù)添加成功修噪!</p>")

啟動服務器并訪問

python manage.py runserver #啟動服務器

#訪問 http://127.0.0.1:8000/testdb/
#看到頁面輸出:數(shù)據(jù)添加成功

查看數(shù)據(jù)庫

image.png
獲取數(shù)據(jù)、刪除、修改

參考

#獲取
# 通過objects這個模型管理器的all()獲得所有數(shù)據(jù)行强法,相當于SQL中的SELECT * FROM
list = Test.objects.all()

# filter相當于SQL中的WHERE蓖墅,可設置條件過濾結果
response2 = Test.objects.filter(id=1) 

# 獲取單個對象
response3 = Test.objects.get(id=1) 

# 限制返回的數(shù)據(jù) 相當于 SQL 中的 OFFSET 0 LIMIT 2;(分頁)
Test.objects.order_by('name')[0:2]

#數(shù)據(jù)排序
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的數(shù)據(jù)
test1 = Test.objects.get(id=1)
test1.delete()

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

# 刪除所有數(shù)據(jù)
Test.objects.all().delete()

異常

刪除數(shù)據(jù)庫表后無法更新

問題:修改模型后無法更新數(shù)據(jù)庫表結構捆交,刪除后再執(zhí)行命令也不行系忙。參考

解決:

  1. 刪除app/migrations/目錄下 “_pycache_” 文件

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

  3. 刪除對應數(shù)據(jù)庫中django_migrations表中app名稱所在的列

    (或者delete from django_migrations where app=‘yourappname’;)戒财,解決無法生成表

表單

HTML表單是網(wǎng)站交互性的經(jīng)典方式幽崩。

HTTP協(xié)議以"請求-回復"的方式工作蹄溉。

  • 客戶發(fā)送請求時宴霸,可以在請求中附加數(shù)據(jù)。
  • 服務器通過解析請求,就可以獲得客戶傳來的數(shù)據(jù)淫痰,并根據(jù)URL來提供特定的服務。

GET

創(chuàng)建一個 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')

#接收請求數(shù)據(jù)
def search(request):
    request.encoding='utf-8'
    if('q' in request.GET and request.GET['q']):
        message = '您搜索的內(nèi)容為:' + request.GET['q']
    else:
        message = '您提交了空表單'
    return HttpResponse(message)

模板目錄 templates 中添加 search_form.html 表單

#/HelloWorld/templates/search_form.html 文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>form_test</title>
</head>
<body>
    <form action="/search/" method="GET">
        <input type="text" name="q">
        <input type="submit" value="搜索">
    </form>
</body>
</html>

urls.py 規(guī)則 添加以下代碼

使用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請求 視圖顯示和請求處理分成兩個函數(shù)處理姑原。

POST

提交數(shù)據(jù)時更常用POST方法。

  • 一個URL和處理函數(shù),同時顯示視圖和處理請求。

Request對象

表單form通過HTTP POST方法提交請求芋膘,但是表單中可以沒有數(shù)據(jù)。

因此童番,不能使用語句if request.POST來判斷是否使用HTTP POST方法;

應該使用if request.method == "POST"

參考1

參考2

參考3

路由

Django不會匹配域名和協(xié)議

舉例:

請求:訪問http://127.0.0.1:8000/polls/34/

Django項目到urls中順序進行正則匹配/polls/34/,匹配到polls/尿赚,就切掉文本"polls/"躲舌,剩余文本"34/"繼續(xù)進行匹配

  • path('polls/',include('polls.urls'))
  • path('<int:question_id>/', views.detail, name='detail')

匹配到了views.detail

得到參數(shù)question_id=34<int:question_id> 匹配生成约计。

  • 使用尖括號“捕獲”這部分 URL尉桩,且以關鍵字參數(shù)的形式發(fā)送給視圖函數(shù)。
  • 上述字符串的 :question_id> 部分定義了將被用于區(qū)分匹配模式的變量名
  • int: 則是一個轉換器決定了應該以什么變量類型匹配這部分的 URL 路徑。

路由簡單的來說就是根據(jù)用戶請求的 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:用于普通路徑,不需要自己手動添加正則首位限制符號猴凹,底層已經(jīng)添加郊霎。
  • 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上捆探,會得到一個分組的參數(shù)

  • 訪問views.login函數(shù)(下方)的參數(shù)除了request搔弄,還需要添加一個參數(shù)(名字隨意)
  • 要設置幾個參數(shù)就要多幾個分組

以下代碼訪問: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<year>[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<name>[a-z]{4})/$',search2.divede_group_name)
image.png

視圖函數(shù)的參數(shù)name 要和有名參數(shù)的名字name一致,否則會報錯兑障!

注意:官方規(guī)定,有名分組和無名分組不能一起使用!

路由分發(fā)(include)

問題:

  • 項目里多個app目錄共用一個 urls 容易造成混淆
  • 后期維護不方便

解決:

  • 使用路由分發(fā)(include)业稼,讓每個app目錄都單獨擁有自己的 urls。

步驟:

  • 1、在每個 app 目錄里都創(chuàng)建一個 urls.py 文件沛膳。
  • 2、在項目名稱目錄下的 urls 文件里落追,統(tǒng)一將路徑分發(fā)給各個 app 目錄妹卿。
舉例:

有兩個app尝偎,都有index.html頁面

  • 如果在項目的urls中配置慷吊,則會造成混淆
  • 且如果有太多的url,則維護十分難

所以應該把各種的url分給各自去管理

#路由 未分發(fā)
#項目主目錄下的urls.py
urlpatterns = [
    url(r'^app-one/index/$',views.index),
    url(r'^app-two/index/$',views.index)
]

新建兩個app

# 語法:python manage.py startapp <app名稱>
# 命令行中運行
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文件榄攀,就能理解路由轉發(fā)了愧捕!

app01

運行項目:python manage.py runserver

image.png

app02

image.png

反向解析

目的:解耦

  • 路由層的 url 發(fā)生變化治力,就需要去更改對應的視圖層和模板層的 url国章,不便維護

反向解析

  • 當路由層 url 發(fā)生改變,在視圖層和模板層動態(tài)反向解析出更改后的 url跛溉,免去修改的操作。
  • 一般用在模板中的超鏈接及視圖中的重定向

問題舉例

#urls.py 中的一條url
...
url(r'^login/$',views.login)
...
#html頁面中的提交表單
<form action="/login/" method="P=post">
    ...
</form>

當更改路由中的url時瓷产,需要在html頁面也做相應的更改循头!

解耦目的:只更改路由中的url,html中會自動做出更改,我們無需去改變!

反向解析

方法:給路由器起別名

應用:

舉例參考

1.普通路徑:name="路由別名

重定向:

  • redirect(reverse("login"))

超鏈接:

  • <form action="{% url 'login' %}" method="post">

2.正則路徑:無名分組

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

重定向:

  • reverse("路由別名"务漩,args=(符合正則匹配的參數(shù),))
    • redirect(reverse("login",args=(10,)))

超鏈接:

  • {% url "路由別名" 符合正則匹配的參數(shù) %}
    • {% url 'login' 10 %}

3.正則路徑:有名分組

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

重定向:

  • reverse("路由別名"竭翠,kwargs={"分組名":符合正則匹配的參數(shù)})
    • redirect(reverse("login",kwargs={"year":3333}))

超鏈接:

  • {% url "路由別名" 分組名=符合正則匹配的參數(shù) %}
    • {% url 'login' year=3333 %}

命名空間

命名空間(英語:Namespace)是表示標識符可見范圍渡八。

一個標識符可在多個命名空間中定義,它在不同命名空間中的含義是互不相干的逮壁。

一個新的命名空間中可定義任何標識符窥淆,它們不會與任何重復的標識符發(fā)生沖突,因為重復的定義都處于其它命名空間中眷昆。

存在問題:路由別名 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('<int:question_id>/', views.detail, name='detail'),
    ...
]
<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>

方式二:

定義命名空間(include 里面是一個元組)

include(("app名稱:urls"罐监,"app名稱"))

實例

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

起別名

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

調(diào)用

#重定向
redirect(reverse("app01:login")
         
#超鏈接
{% url "app名稱:路由別名" %}

視圖

每個視圖必須要做的只有兩件事:

  • 返回一個包含被請求頁面內(nèi)容的 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),
]

使用管理工具

創(chuàng)建超級用戶

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

之前在 TestModel 中已經(jīng)創(chuàng)建了模型 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 中增加一個更復雜的數(shù)據(jù)模型

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

現(xiàn)在只是有了Concate和Tag模型燕侠,在數(shù)據(jù)庫中還沒有對應的表

(Test是文章前面建的)

image.png

使用以下命令創(chuàng)建表結構

python manage.py makemigrations TestModel  # 讓 Django 知道我們在我們的模型有一些變更
python manage.py migrate TestModel   # 創(chuàng)建表結構

第一條命令執(zhí)行完者祖,多了一個文件

image.png

第二條命令執(zhí)行完,創(chuàng)建了對應的表

(有關數(shù)據(jù)庫連接請看“模型”)

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 數(shù)據(jù)模型,我們在注冊的時候茫舶,需要將它們一起注冊

刷新后顯示效果如下

image.png
2.將輸入欄分塊械巡,每個欄也可以定義自己的格式。

注意字母拼寫不要錯誤H氖稀<ズ摹!

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 部分隱藏

內(nèi)聯(lián)(Inline)顯示

上面的 Contact 是 Tag 的外部鍵,所以有外部參考的關系喊崖。

問題:在默認的頁面顯示中挣磨,將兩者分離開來,無法體現(xiàn)出兩者的從屬關系荤懂。

解決:可以使用內(nèi)聯(lián)顯示茁裙,讓 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 輸入數(shù)條記錄后节仿,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

一個項目中可以創(chuàng)建很多個app

app可以用路由分發(fā)解決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
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末查近,一起剝皮案震驚了整個濱河市眉踱,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌霜威,老刑警劉巖谈喳,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異戈泼,居然都是意外死亡婿禽,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進店門大猛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來扭倾,“玉大人,你說我怎么就攤上這事挽绩√乓迹” “怎么了?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵唉堪,是天一觀的道長模聋。 經(jīng)常有香客問我,道長唠亚,這世上最難降的妖魔是什么链方? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮灶搜,結果婚禮上祟蚀,老公的妹妹穿的比我還像新娘。我一直安慰自己割卖,他們只是感情好暂题,可當我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著究珊,像睡著了一般薪者。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上剿涮,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天言津,我揣著相機與錄音,去河邊找鬼取试。 笑死悬槽,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的瞬浓。 我是一名探鬼主播初婆,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了磅叛?” 一聲冷哼從身側響起屑咳,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎弊琴,沒想到半個月后兆龙,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡敲董,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年紫皇,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片腋寨。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡聪铺,死狀恐怖贺嫂,靈堂內(nèi)的尸體忽然破棺而出迄委,到底是詐尸還是另有隱情捕透,我是刑警寧澤魏烫,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站灾而,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜赖阻,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望踱蠢。 院中可真熱鬧火欧,春花似錦、人聲如沸茎截。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽企锌。三九已至榆浓,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間撕攒,已是汗流浹背陡鹃。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留抖坪,地道東北人萍鲸。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像擦俐,于是被迫代替她去往敵國和親脊阴。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,614評論 2 353

推薦閱讀更多精彩內(nèi)容