目錄html
在一個表中插入不少條的數據,你應該很快就能想到用create,然而事實是這樣嗎?前端
def index(request): book_list=[] for i in range(1000): #models.Book.objects.create(title=f'第{i}本書') book=models.Book(title=f'第{i}本書') book_list.append(book) models.Book.objects.bulk_create(book_list) book_query=models.Book.objects.all() return render(request,'index.html',locals())
<body> {%for i in book_query%} <p> {{i.title}} </p> {%endfor%} </body>
就像上面註釋的代碼是否是你的想法呢,想法能夠,但實現着實困難了點,一旦數據多了,就會形成數據庫的龐大壓力,而使用bulk_create一步到位,用哪一種方法就顯而易見了-。-python
這個東西聽上去是否是有點d,凡是自定義的,總感受是比通常的高端一點,反正我是這麼認爲的|^ _ ^|數據庫
這裏只提供思路啊,代碼就由你去實現了,fighting!django
首先咱們是否是須要定義一些變量來存總頁數,數據總量,每頁數據量等等。。。後端
current_page=request.GET.get('page',1) #獲取用戶想要訪問的頁碼數,若是沒有則默認第一頁 current_page=int(current_page) #轉成整形 per_page_num=10 #定義一下每頁須要多少條數據,這裏定義成10條哦 start_page=(current_page-1)*per_page_num #每一頁的初始位置 end_page=current_page*per_page_num #每一頁的末尾位置 book_query=models.Book.objects.all() all_count=book_query.count() #統計數據總量 #這裏須要用到一個divmod方法,來求出須要的總頁數 page_num,more=divmod(all_count,per_page_num) if more: page_num+=1 page_html='' #這是待會要傳回前端頁面的標籤 x=current_page #先保存一下,以避免待會數據發生變化 if current<6: #小於第6頁,就不會再往前滑動 current=6 for i in range(current_page-5,current_page+6): #一共展現11頁 if x=i: page_html+=''<li class="active"><a href="?page=%s">%s</a></li>'%(i,i)'#設置高亮 else: page_html += '<li><a href="?page=%s">%s</a></li>' % (i, i) book_query=book_query[start_page:end_page] return render(request,'index.html',locals())
{% for book_obj in book_queryset %} <p>{{ book_obj.title }}</p> {% endfor %} <nav aria-label="Page navigation"> <ul class="pagination"> <li> <a href="#" aria-label="Previous"> <span aria-hidden="true">«</span> </a> </li> {{ page_html|safe }} <li> <a href="#" aria-label="Next"> <span aria-hidden="true">»</span> </a> </li> </ul> </nav>
哎,嘴上雖說着不寫代碼了,手仍是很誠實的,真是沒辦法啊-_-安全
以上就是自定義分頁器的內容了,不過呢,強大的python怎麼會沒有一個這樣的模塊給咱們使用呢?app
就很少bb了,直接上代碼函數
from app01.utils.mypage import Pagination def login(request): book_query=models.Book.objects.all() current_page=request.GET.get('page',1) all_count=book_queryset.count() #實例化產生對象 page_obj=Pagination(current_page=current_page,all_count=all_count) #切片操做 page_queryset=page_queryset[page_obj.start:page_obj.end] return render(request,'login.html',locals())
模塊中封裝的分頁器是真他媽的香啊。。。post
orm一上來就本身動(手建表),這個就不用我多說了吧,你們都懂的(邪魅一笑...)
好處在於他會幫你建立第三張表,但不能對第三張表中的字段進行二次操做,擴展性就比較差了
class Book(models.Model): ... authors = models.ManyToManyField(to='Author') class Author(models.Models): ...
這個一看就感受很麻煩了吧,並且居然還有另外的缺點,orm查詢時不少方法都不支持,查詢起來就比較麻煩,很少說,果斷放棄吧
class Book(models.Model): ... class Author(models.Models): ... class Book2Author(models.Model): book_id = models.ForeignKey(to='Book') author_id = models.ForeignKey(to='Author') create_time = models.DateField(auto_now_add=True) ...
orm親兒子,懂吧?
推薦指數6顆星,手動建表,可是會通知orm這表是本身建的,orm提供各類方法就好了,不過有四種方法仍然不支持add,set,remove,clear,不過問題不大哈
class Book(models.Model): ... authors = models.ManyToManyField(to='Author', through='Book2Author', through_fields=('book','author')) ''' class Author(models.Model): ... books = models.ManyToManyField(to='Book', through='Book2Author', through_fields=('author', 'book')) ''' class Book2Author(models.Model): book = models.ForeignKey(to='Book') author = models.ForeignKey(to='Author') create_time = models.DateField(auto_now_add=True) ... # 1.半自動 必定要加兩個額外的參數 through='Book2Author', through_fields=('book','author') # 2.後面字段的順序 由第三張表經過哪一個字段查詢單表 就把哪一個字段放前面
萬萬沒想到,從這裏纔開始重點,我太難了啊 T.T
開始了啊,加入咱們要設計一個註冊頁面,用戶name不能包含dsb這串字符,密碼不小於3位,這顯然比較簡單
def reg(request): back_dic={'username':'','password':''} if request.method=='POST': username=request.POST.get('username') password=request.POSt.get('password') if 'dsb' in username: back_dic['username']='你輸入的用戶名不符合社會主義核心價值觀' if len(password)<3: back_dic['password']='過短了哦,嫌棄ing' return render(request,'reg.html',local())
<form action="" method="post"> <p>username: <input type="text" name="username"> <span style="color: red">{{ back_dic.username }}</span> </p> <p>password:<input type="text" name="password"> <span style="color: red">{{ back_dic.password }}</span> </p> <input type="submit"> </form>
這樣寫起來,若是有不一樣的輸入錯誤狀況顯然比較麻煩,因此就要用到form組件了
首先,寫一個類
from django import forms class Myform(forms.Form): username=forms.CharField(min_length=3,max_length=8) password=forms.CharField(min_length=3,max_length=8) email=forms.EmailField() #如何校驗數據 from app01 import views obj=views.Myform({'username':'jason','password':'123','email':'123'}) #判斷數據是否合法 obj.is_valid() #查看符合條件的數據 obj.cleaned_data #查看不符合條件的數據 obj.errors #須要注意的是,全部的參數必須傳值,能夠多傳,不能少傳
封裝成度過高,可擴展性差
<p> {{form_obj.as_p}} {{form_obj.as_ul}} </p>
<p> {{ form_obj.username.label }}{{ form_obj.username }} </p> <p> {{ form_obj.password.label }}{{ form_obj.password }} </p> <p> {{ form_obj.email.label }}{{ form_obj.email }} </p>
手寫代碼量太多,明顯不方便
推薦使用
{% for foo in form_obj %} <p>{{ foo.label }}{{ foo }}</p> {% endfor %}
因爲form組件會自動前端校驗數據,但前端校驗又不太安全,因此咱們取消他,來後端校驗
在前端中的form表單中添加參數novalidata便可
<!--展現錯誤信息 用對象點errors.0--> <form action="" method="post" novalidate> {% for foo in form_obj %} <p> {{ foo.label }}:{{ foo }} <span style="color: red">{{ foo.errors.0 }}</span> </p> {% endfor %} <input type="submit"> </form>
設置錯誤信息
from django import forms class MyRegForm(forms.Form): username = forms.CharField(min_length=3,max_length=8,label='用戶名', error_messages={ 'min_length':'用戶名最短三位', 'max_length':'用戶名最長八位', 'required':'用戶名不能爲空' },initial='我是初始值',required=False ) password = forms.CharField(min_length=3,max_length=8,label='密碼',error_messages={ 'min_length':'密碼最短三位', 'max_length':'密碼最長八位', 'required':'密碼不能爲空' }) email = forms.EmailField(label='郵箱',error_messages={ 'required':'郵箱不能爲空', 'invalid':'郵箱格式不正確' },required=False)
針對字段 你能夠作額外的校驗 經過鉤子函數
# 當你須要對某一個字段數據進行額外的一些列校驗 你能夠考慮使用鉤子函數 # 針對單個字段的 使用局部鉤子 def clean_username(self): username = self.cleaned_data.get('username') if 'dsb' in username: # 給username字段下面提示錯誤信息 self.add_error('username','用戶名不符合社會主義核心價值觀') return username
def clean(self): password=self.cleaned_data.get('password') if not password == confirm_password: self.add_error('confirm_password','兩次密碼不一致') return self.cleaned_data
from django import forms from django.forms import Form from django.core.validators import RegexValidator class MyForm(Form): user = forms.CharField( validators=[RegexValidator(r'^[0-9]+$', '請輸入數字'), RegexValidator(r'^159[0-9]+$', '數字必須以159開頭')], )
widget= widgets.TextInput() widget=widgets.PasswordInput() 如何讓forms組件渲染出來的input框有form-control類屬性 widget= widgets.TextInput(attrs={'class':'form-control others'}) # 若是有多個類屬性 空格隔開 widget=widgets.PasswordInput(attrs={'class':'form-control others'})