?一.項目創建
- 在想要將項目創鍵的目錄下,輸入cmd? ?(進入命令提示符)
- 在cmd中輸入:Django-admin startproject 項目名稱? (創建項目)
- cd 項目名稱? (進入項目)
- Django-admin startapp 程序名稱? (創建程序)
- python manage.py runserver 8080? (運行程序)
- 將彈出的網址復制到瀏覽器中http://127.0.0.1:8080/?
當出現這個界面時說明運行成功了
二.設置settings
一.installed_apps
在INSTALLED_APPS中將我們創建的myday程序名稱輸入
INSTALLED_APPS = ['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','myday'
]
二.templates
在根目錄下創建templates文件夾,并將TEMPLATES中的'DIRS'修改為如圖所示
TEMPLATES = [{'BACKEND': 'django.template.backends.django.DjangoTemplates','DIRS': [os.path.join(BASE_DIR,'templates')],'APP_DIRS': True,'OPTIONS': {'context_processors': ['django.template.context_processors.debug','django.template.context_processors.request','django.contrib.auth.context_processors.auth','django.contrib.messages.context_processors.messages',],},},
]
三.databases
在DATABASES中按如下格式輸入,將數據庫改為MYSQL數據庫
DATABASES = {'default': {'ENGINE': 'django.db.backends.mysql','NAME': '數據庫名','USER': 'root','PASSWORD': 'MYSQL密碼','HOST': '127.0.0.1','PORT': '3306', }
}
?注意:因為在python3中mysql改名為pymysql所以需要在主目錄下的_init_中輸入
import pymysql
pymysql.install_as_MySQLdb()
四.漢化
最后這樣進行漢化處理
LANGUAGE_CODE = 'zh-hans'TIME_ZONE = 'Asia/shanghai'
三.模型類設置
1.字段類型
- AutoField:自動增長的IntegerField,通常不用指定,不指定時Django會自動創建屬性名為id的自動增長屬性
- BooleanField:布爾字段,值為True或False
- NullBooleanField:支持Null、True、False三種值
- CharField(max_length=字符長度):字符串,必選 參數max_length表示最大字符個數
- TextField:大文本字段,一般超過4000個字符時使用
- IntegerField:整數
- DecimalField(max_digits=None, decimal_places=None):十進制浮點數參數max_digits表示總位數,參數decimal_places表示小數位數
- FloatField:浮點數
- DateField[auto_now=False, auto_now_add=False]):日期 參數auto_now表示每次保存對象時,自動設置該字段為當前時間,用于"最后一次修改"的時間戳,它總是使用當前日期,默認為false,參數auto_now_add表示當對象第一次被創建時自動設置當前時間,用于創建的時間戳,它總是使用當前日期,默認為false,參數auto_now_add和auto_now是相互排斥的,組合將會發生錯誤
- TimeField:時間,參數同DateField
- DateTimeField:日期時間,參數同DateField
- FileField:上傳文件字段
- ImageField:繼承于FileField,對上傳的內容進行校驗,確保是有效的圖片
關系型數據庫的關系包括三種類型:
- ForeignKey:一對多,將字段定義在多的一端中
- ManyToManyField:多對多,將字段定義在兩端中
- OneToOneField:一對一,將字段定義在任意一端中
2.定義模型-models
from django.db import models
# Create your models here.
class Tag(models.Model):Tag_name = models.CharField(max_length=50, unique=True)def __str__(self):return self.Tag_nameclass Meta:verbose_name_plural = '標簽名'class Category(models.Model):Category_name = models.CharField(max_length=50, unique=True)def __str__(self):return self.Category_nameclass Meta:verbose_name_plural = '分類名'class Post(models.Model):title = models.CharField("題目", max_length=50, unique=True)content = models.TextField("內容")author = models.CharField("作者", max_length=200, default="郭十一")tag = models.ManyToManyField(Tag)category = models.ForeignKey(Category, on_delete=models.CASCADE, null=True) # 這里的NULL表示,數據分類可以為空def __str__(self):return self.titleclass Meta:verbose_name_plural = "內容"
?Meta既對如下進行的修改顯示
3.定義模型-admin
?在注冊這三個表時,admin會自行運行里面的方法,所以不用調用
from django.contrib import admin
from .models import Category, Post,Tag
#第二種注冊表的方法:admin.site.register(Category)@admin.register(Post)
class PostAdmin(admin.ModelAdmin):#顯示設置list_display = ['title','content','author','display_tag','display_category'] #因為不能顯示多對多,所以要美化#區塊設置fieldsets =(("標題/正文", {'fields': ['id','title', 'content'], 'classes': ['collapse']}),("作者", {'fields': ['author'], 'classes': ['collapse']}),("分類/標簽", {'fields': ['tag','category'], 'classes': ['collapse']}),)#搜索功能search_fields = ['title', 'content','author','category__Category_name','tag__Tag_name']#過濾功能list_filter = ['author','category','tag']#分頁功能list_per_page = 3def display_tag(self, obj):return "/".join([tag.Tag_name for tag in obj.tag.all()])display_tag.short_description = "標簽"def display_category(self, obj):return obj.category.Category_namedisplay_category.short_description = "分類"class PostInlines(admin.StackedInline): #StackedInline是上下布局,TabularInline左右布局model = Post #關聯的類extra = 3 #空白3篇@admin.register(Category) #第二類注冊方式
class CategoryAdmin(admin.ModelAdmin):list_display = ('display_category','id') #與PostAdmin相同,顯示設置,需要自定義方法def display_category(self, obj):return obj.Category_namedisplay_category.short_description = "分類"@admin.register(Tag)
class TagAdmin(admin.ModelAdmin):list_display = ('display_tag','id') #與PostAdmin相同,顯示設置,需要自定義方法def display_tag(self, obj):return obj.Tag_namedisplay_tag.short_description = "標簽"
使用display_tag方法自定義的列名,并使用list_display顯示
4.模型類成員
- save():將模型對象保存到數據表中
- delete():將模型對象從數據表中刪除
1.方法一:
在views中,編寫視圖函數進行數據的保存與刪除
from django.shortcuts import render,HttpResponse
from .models import *def save_tag(request,tag_name):tag = Tag()tag.Tag_name = tag_nametag.save()return HttpResponse(f"已成功添加{tag_name}")def delete_tag(request,tag_name):tag = Tag.objects.get(Tag_name=tag_name)tag.delete()return HttpResponse(f"已成功刪除{tag_name}")
?配置主路由
from django.contrib import admin
from django.urls import path,includeurlpatterns = [path('admin/', admin.site.urls),path('',include('myday.urls')),
]
再使用正則配置子路由
from django.contrib import admin
from django.urls import path,include,re_path
from .views import *
urlpatterns = [re_path(r"save_tag/(\w+)",save_tag),re_path(r"delete_tag/(\w+)",delete_tag)
]
2.方法二:
自定義管理器類主要用于兩種情況 :
- 修改原始查詢集,重寫get_queryset()方法
- 向管理器類中添加額外的方法,如創建對象
在models中進行自定義管理器的編寫
from django.db import models# Create your models here.
class PostManage(models.Manager):def get_queryset(self):#return super(PostManage,self).get_queryset() #不變return super(PostManage,self).get_queryset().filter(deleted=False) #只返回沒有被邏輯刪除的部分def create(self,title,content,author,category):p = self.model() # 創建模型類對象self.model可以獲得模型類p.title = titlep.content = contentp.author = authorp.category = categoryp.delete = Falsereturn p # 返回模型對象class Post(models.Model):#...其他代碼post_object = PostManage()
在視圖中進行視圖函數編寫
def add_post(request):title = 'python 高級快速入門4'content = 'python 大法好'author = Post.post_object.get(id=1).author # 作者# category = Category() # 創建分類# category.category_name = 'python高級'# category.save()#或使用:因為在這兩個表中的object沒有被覆蓋category, created = Category.objects.get_or_create(Category_name='Python高級' # 嘗試獲取或創建)# 2. 同樣的邏輯處理標簽tag, created = Tag.objects.get_or_create(Tag_name='Python大法')# tag = Tag() # 創建標簽# tag.tag_name = 'python大法'# tag.save()p = Post.post_object.create(title,content,author,category) #將帶有數據的模型對象返回p.save()p.tag.add(tag) # 添加標簽return HttpResponse('添加成功')
配置url
urlpatterns = [path("add_post",add_post)
]
5.查詢集
1.返回列表的過濾器如下:
- all():返回所有數據
- filter():返回滿足條件的數據
- exclude():返回滿足條件之外的數據,相當于sql語句中where部分的not關鍵字
- order_by():排序,參數為字段名,-號表示降序
def show_post(request):All = Post.post_object.all()Filter = Post.post_object.filter(category__Category_name__contains='Python')exclude = Post.post_object.exclude(category__Category_name__contains='Python')order =Post.post_object.filter(category__Category_name__contains='Python').order_by('tag')print("返回全部:",All)print("返回分類包含Python的:",Filter)print("返回分類不包含Python的:",exclude)print("返回排序:",order)return HttpResponse("返回成功")
返回全部: <QuerySet [<Post: 1>, <Post: 2>, <Post: python 高級快速入門>, <Post: python 高級快速入門2>, <Post: python 高級快速入門3>, <Post: python 高級快速入門4>]>
返回分類包含Python的: <QuerySet [<Post: python 高級快速入門>, <Post: python 高級快速入門2>, <Post: python 高級快速入門3>, <Post: python 高級快速入門4>]>
返回分類不包含Python的: <QuerySet [<Post: 1>, <Post: 2>]>
返回排序: <QuerySet [<Post: python 高級快速入門>, <Post: python 高級快速入門2>, <Post: python 高級快速入門3>, <Post: python 高級快速入門4>]>
2.返回單個值的過濾器如下:
- get():返回單個滿足條件的對象 如果未找到會引發"模型類.DoesNotExist"異常 如果多條被返回,會引發"模型類.MultipleObjectsReturned"異常
- count():返回當前查詢的總條數
- exists():判斷查詢集中是否有數據,如果有則返回True,沒有則返回False
category__Category_name__contains:兩個下滑線的意思類似于category.Category_name.contains
Post.post_object.all().count()
3
Post.post_object.all().exists() # 查詢結果集有數據,exists返回True
True
Post.post_object.filter(id=1000).exists() # 數據中不存在id為1000的數據,查詢結果集為空,返回False
False
運算符如下:
exact:表示相等
contains:是否包含
startswith、endswith:以指定值開頭或結尾
iexact,icontains,istartswith,iendswith功能同上面四個一樣,前面加字母i表示不區分大小寫。
isnull:是否為null
in:是否包含在范圍內
gt:大于
gte:大于等于
lt:小于
lte:小于等于
exclude()方法:返回滿足條件之外的數據,實現不等于效果
year、month、day、week_day、hour、minute、second:對日期時間類型的屬性進行運算
F對象 專門取對象中某列值的操作,F() 返回的實例用作查詢內部對模型字段的引用。這些引用可以用于查詢的filter 中來比較相同模型實例上不同字段之間值的比較。
Q對象 邏輯運算
注意:在django中查詢條件的運算符采用兩個下劃線連接。 比如:
Post.post_object.filter(id__exact=1) #查詢條件:id等于1的數據
id大于1的數據:
Post.post_object.filter(id__gt=1)
翻譯成sql語句為:
select * from Post where id>1;
演示:
- exact 等于 查詢id等于1的數據
Post.post_object.filter(id__exact=1) #查詢條件:id等于1的數據,注意是兩個下劃線
djago查詢中條件查詢默認使用exact運算符。 查詢相等可簡寫:
Post.post_object.filter(id=1)
- contains:是否包含 查詢標題(title字段) 中包含'django'的文章
>>> Post.post_object.filter(title__contains='django')
<QuerySet [<Post: e10分鐘入門django>, <Post: django 快速開發>]>
- startswith、endswith:以指定值開頭或結尾
查詢標題中以python開頭的文章
>>> Post.post_object.filter(title__startswith='python')
<QuerySet [<Post: python 高級快速入門>]>
查詢標題中以django結尾的文章
>>> Post.post_object.filter(title__endswith='django')
<QuerySet [<Post: e10分鐘入門django>]>
- isnull:是否為null 如果數據庫中有字段值為null的不能直接使用 '字段=null' 的方式查詢,需要使用isnull判斷值是否為null
>>> Post.post_object.filter(title__isnull=False) #查詢文章標題不為null的數據
<QuerySet [<Post: python 高級快速入門>, <Post: e10分鐘入門django>, <Post: django 快速開發>]>
>>> Post.post_object.filter(title__isnull=True) <p>#查詢文章標題為null的數據</p>
<QuerySet []>
- in:是否包含在范圍內 查詢id為2、3,4的文章,參數是一個列表,id在列表中,就是符合條件的。
>>> Post.post_object.filter(id__in=[2,3,4])
<QuerySet [<Post: e10分鐘入門django>, <Post: django 快速開發>]>
- gt:大于 查詢id大于3 的文章
>>> Post.post_object.filter(id__gt=3)
<QuerySet [<Post: python 高級快速入門>, <Post: django 快速開發>]>
- gte:大于等于 查詢id大于等于3 的文章
>>> Post.post_object.filter(id__gte=3)
<QuerySet [<Post: python 高級快速入門>, <Post: e10分鐘入門django>, <Post: django 快速開發>]>
- lt:小于 查詢id小于4的文章
>>> Post.post_object.filter(id__lt=4)
<QuerySet [<Post: e10分鐘入門django>]>
- lte:小于等于 查詢id小于等于4的文章
>>> Post.post_object.filter(id__lte=4)
<QuerySet [<Post: e10分鐘入門django>, <Post: django 快速開發>]>
- year、month、day、week_day、hour、minute、second:對日期時間類型的屬性進行運算 查詢2018年寫的文章:
>>> Post.post_object.filter(created_time__year=2018)
<QuerySet [<Post: python 高級快速入門>, <Post: e10分鐘入門django>]>
查詢2018年之前寫的文章
>>> Post.post_object.filter(created_time__year__lt=2018)
<QuerySet [<Post: django 快速開發>]>
查詢2018年1月1日之后的文章
>>> Post.post_object.filter(created_time__gte=date(2018,1,1))
F對象
如果查詢條件為兩個屬性值比較那么需要用到F對象。使用F對象,被定義在django.db.models中所有要使用F對象要先導入
導入F對象。
from django.db.models import F
F() 返回的實例用作查詢內部對模型字段的引用。這些引用可以用于查詢的filter 中來比較相同模型實例上不同字段之間值的比較。
>>> Post.post_object.filter(created_time=F('modified_time'))
<QuerySet [<Post: python 高級快速入門>]>
Django 支持對F() 對象使用加法、減法、乘法、除法、取模以及冪計算等算術操作,兩個操作數可以都是常數和其它F() 對象。
比如:查詢閱讀量大于兩倍評論量的數據
Post.post_object.filter(read__gt=F('comment')*2)
Q對象:Q對象,被定義在django.db.models中所有要使用Q對象要先導入
from django.db.models import Q
兩個條件邏輯與運算在多個條件用逗號分隔就是邏輯與:
>>> Post.post_object.filter(title='django 快速開發',id__gt=2)
<QuerySet [<Post: django 快速開發>]>
如果需要實現邏輯或or的查詢,需要使用Q()對象結合|運算符 Q對象可以使用&、|連接,&表示邏輯與,|表示邏輯或 Q對象使用~操作符,表示邏輯非,not
例如:查詢標題以django結尾或者python開頭的文章。這種邏輯或的關系,直接查詢是沒辦法查詢的,需要使用Q對象結合 | 查詢
>>> Post.post_object.filter(Q(title__startswith='python') | Q(title__endswith='django'))
<QuerySet [<Post: python 高級快速入門>, <Post: e10分鐘入門django>]>
相當于mysql中的語句:
WHERE title LIKE 'python%' OR title LIKE '%django'
查詢 id不等于3的文章:
>>> Post.post_object.filter(~Q(id=3))
<QuerySet [<Post: python 高級快速入門>, <Post: django 快速開發>]>
3、關聯查詢
Django中也能實現類似于mysql中的連接查詢。
關聯模型類名小寫屬性名運算符=值
例如:查詢分類為'django'的文章
>>> Category.objects.filter(post__title='django 快速開發')
<QuerySet [<Category: django>]>
查詢分類為django的所有文章
>>> Post.post_object.filter(category__category_name='django')
<QuerySet [<Post: e10分鐘入門django>, <Post: django 快速開發>]>
4、反向查詢
如果模型I有一個ForeignKey,那么該ForeignKey 所指的模型II實例可以通過一個管理器返回前面有ForeignKey的模型I的所有實例。這個管理器的名字為foo_set,其中foo是源模型的小寫名稱。
>>> cg = Category.objects.filter(category_name='django')[0]
>>> cg
<Category: django>
>>> cg.post_set.all()
<QuerySet [<Post: e10分鐘入門django>, <Post: django 快速開發>]>
5、聚合函數
使用aggregate()過濾器調用聚合函數, 常用聚合函數:Avg,Count,Max,Min,Sum,被定義在django.db.models中 需要使用要先導入聚合函數
聚合函數返回結果是一個字典:
>>> from django.db.models import Max
>>> Post.post_object.aggregate(Max('id')) # 查詢文章表中id的最大值
{'id__max': 7}>>> from django.db.models import Min
>>> Post.post_object.aggregate(Min('id')) # 查詢文章表中id的最小值
{'id__min': 3}>>> from django.db.models import Avg
>>> Post.post_object.aggregate(Avg('id')) # 查詢所有文章id的平均數
{'id__avg': 4.666666666666667}
>>> from django.db.models import Count
>>> Post.post_object.aggregate(Count('id')) #統計一共多少文章。
{'id__count': 3}
>>> from django.db.models import Sum
>>> Post.post_object.aggregate(Sum('id'))
{'id__sum': 14}