django 之知識點總結以及Form組件


一、model常用操作

  1、13個API查詢:all,filter,get ,values,values_list,distinct,order_by ,reverse , exclude(排除),count,first,last,esits(判斷是否存在)

  需要掌握的all、values、values_list的區別

    all:打印的是一個QuerySet集合,一個列表里面放的對象

    values :是一個字典形式

    values_list:是一個元組形式  

  all的性能是最低的

  2、only和defer

datalist = models.Userinfo.objects.all().only("name","email")  #拿到的還是一個QuerySet集合,僅僅取name和email
for item in datalist:
    print(item.id)
    print(item.name)
    print(item.pwd)   #只要表里有這個字段,一樣會取到值,額外的會再發一次請求

datalist = models.Userinfo.objects.all().defer("name","email") #阻止,不取name和email
for item in datalist:
    print(item.id)
    print(item.pwd)

  注意:用only的話就去取only里面的字段,取其他的字段效率太低了,盡可能的少的連接數據庫

  3、路由系統

  反向生成URL:

    有兩種方式:{% url "a1" %}

          reverse("a1")

用reverse需要導入     from django.core.urlresolvers import reverse

/index/     func    name=a1
    {% url "a1"}
     reverse('a1')
                
/index/(\d+)/     func    name=a2
    {% url "a2" 11 %}
    reverse('a2',args=(11,))
                
/index/(?P<nid>\d+)/     func    name=a3
    {% url "a2" nid=11 %}
    reverse('a3',kwargs={'nid':11})

 

 4、Django的生命周期

               Web服務器網關接口(Python Web Server Gateway Interface,縮寫為WSGI)

    1、首先走wsgi模塊,這個模塊也是一個協議,包括wsgiref和uwsgi。

    2、然后路由分配-------views視圖

    3、從數據庫取數據-----------渲染到html

    注意如果導入js文件,是不會渲染的。

  5、HTTP協議

    詳見下一篇博客                                                                                                

二、Form組件

一、Form組件介紹

Form組件可以做的幾件事情:

  1、用戶請求數據驗證

  2、自動生成錯誤信息    

  3、打包用戶提交的正確信息

  4、如果其中有一個錯誤了,其他的正確這,保留上次輸入的內容

  4、自動創建input標簽並可以設置樣式

二、Form組件的使用

  1、創建規則

class Foo(Form): #必須繼承
    username = xxx
    password = xxx
    email = xxx
注意這里的字段必須和input的name字段一致

 

  2、數據和規則進行匹配

先導入view.py

from django.forms import Form
from django.forms import fields
from django.forms import widgets

 

from django.shortcuts import render,redirect
from app01 import models
# Create your views here.
from django.forms import Form
from django.forms import fields
from django.forms import widgets
# 1、創建規則
class TeacherForm(Form):  #必須繼承Form
    # 創建字段,本質上是正則表達式
    username = fields.CharField(
        required=True,     #必填字段
        error_messages={"required":"用戶名不能為空!!"},  #顯示中文錯誤提示
        widget=widgets.TextInput(attrs={"placeholder":"用戶名","class":"form-control"})  #自動生成input框
       )
    password = fields.CharField(required=True, error_messages={'required': '密碼不能為空'},
                                widget=widgets.TextInput(attrs={'placeholder': '密碼', 'class': 'form-control'}))  # 不能為空
    email = fields.EmailField(
        required=True,
        error_messages={"required":"郵箱不能為空!!","invalid":"無效的郵箱"},
        widget=widgets.EmailInput(attrs={"placeholder": "郵箱", "class": "form-control"})  # 自動生成input框
    ) #不能為空且郵箱格式要一致

# 2、使用規則:將數據和規則進行匹配
def teacherindex(request):
    teacher_obj = models.UserInfo.objects.all()
    # print(teacher_obj)
    return render(request,"teacherindex.html",{"teacher_obj":teacher_obj})
def add(request):
    if request.method=="GET":
        form = TeacherForm()  #只是讓顯示一個input框
        return render(request,"add.html",{"form":form })
    else:
        form = TeacherForm(data=request.POST)
        # print(form)  #<QuerySet [<UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>]>
        if form.is_valid():# 開始驗證
            # print('執行成功',form.cleaned_data)          # 所有匹配成功,字典
            # {'username': 'asd', 'password': 'sdf', 'email': 'sadf@live.com','ut_id':1}
            form.cleaned_data['ut_id'] = 1  #要分的清是班主任還是講師
            models.UserInfo.objects.all().create(**form.cleaned_data)
            return redirect("/teacherindex/")
        else:
            # print("=====?",form.errors,type(form.errors))#返回失敗的結果
            # print(form.errors["username"][0])   #拿到返回失敗的結果,渲染到頁面
            return render(request,"add.html",{"form":form})

 

html.py

{% block right %}
    <h1>添加老師信息</h1>
    <hr>
    <form method="post" novalidate>
        {% csrf_token %}
        <p>姓名:{{ form.username }}</p>{{ form.errors.username.0 }}
        <p>密碼:{{ form.password }}</p>{{ form.errors.password.0 }}
        <p>郵箱:{{ form.email }}</p>{{ form.errors.email.0 }}
        <p><input type="submit" value="提交"></p>
    </form>
{% endblock %}

如果訪問視圖的是一個GET 請求,它將創建一個空的表單實例並將它放置到要渲染的模板的上下文中。這是我們在第一個訪問該URL 時預期發生的情況。

如果表單的提交使用POST 請求,那么視圖將再次創建一個表單實例並使用請求中的數據填充它:form = NameForm(request.POST)。這叫做”綁定數據至表單“(它現在是一個綁定的表單)。

我們調用表單的is_valid()方法;如果它不為True,我們將帶着這個表單返回到模板。這時表單不再為空(未綁定),所以HTML 表單將用之前提交的數據填充,然后可以根據要求編輯並改正它。

如果is_valid()True,我們將能夠在cleaned_data 屬性中找到所有合法的表單數據。在發送HTTP 重定向給瀏覽器告訴它下一步的去向之前,我們可以用這個數據來更新數據庫或者做其它處理。

注意: form = TeacherForm()  #沒有參數,只是一個input框

    form = TeacherForm(data=request.POST) # 數據和規則放置一起 (添加的時候用)

    form = TeacherForm(initial={'username':obj.username,'password':obj.password,'email':obj.email})   # 顯示input,並且將數據庫中的默認值填寫到input框中 (編輯的時候用)

 

Widgets

每個表單字段都有一個對應的Widget 類,它對應一個HTML 表單Widget,例如<input type="text">

在大部分情況下,字段都具有一個合理的默認Widget。例如,默認情況下,CharField 具有一個TextInput Widget,它在HTML 中生成一個<input type="text">

字段的數據

不管表單提交的是什么數據,一旦通過調用is_valid() 成功驗證(is_valid() 返回True),驗證后的表單數據將位於form.cleaned_data 字典中。這些數據已經為你轉換好為Python 的類型。

注:此時,你依然可以從request.POST 中直接訪問到未驗證的數據,但是訪問驗證后的數據更好一些。

在上面的聯系表單示例中,is_married將是一個布爾值。類似地,IntegerField 和FloatField 字段分別將值轉換為Python 的int 和float

三、數據庫表設計

設計表時注意的幾點:

  1、 nid = models.AutoField(primary_key=True)        #如果不指定django會默認加上id的

    nid = models.BigAutoField(primary_key=True)   #但那些整型滿足不了你的時候,就用BigAutoField

  2、對於類的注釋一般加在類里面

  3、verbose_name=“標題”   字段的中文提示

  4、ForeignKey(to = "表名",tofield= "字段")    #這兩個to可以不用寫,但是關聯的表名一定要寫

  5、releated_name = "uuu"   反向查詢。如果一個表中有多個ManyTwoMany()或者ForeignKey()必須加上releated_name 

  6、字段經常變動的適合連表

     字段變化小,不怎么變的適合在一個表中,不進行連表:就用choices

       吧班主任和老師可以放到一個表中、因為他們有相同的屬性,如果屬性全是一樣的,可以放在一個表里(推薦)

     也可以分開放,老師表是老師表,班主任表是班主任表。這樣就會進行連表操作,連表有性能消耗。

舉例:文章和文章類型

   分析:一個文章有一個類型,一個類型可以對應多個文章(所以文章和文章類型是一對多的關系,關聯字段要放在多的一方)

  一:連表設計:

class News(models.Model):
    title = models.CharField(max_length=32)
    summary = models.CharField(max_length=255)
    news_type = models.ForeignKey(to="NewsType")
class NewsType(models.Model):
    type_title = models.CharField(max_length=32)

News:

  id   title   summary  news_type_id
  1    t....    科技...     2
  2    t....    科技...     1
  3    t....    科技...     2

NewsType:
 id title

  1      圖片
  2      挨踢1024
  3      段子

 

# 查看所有新聞
new_list = models.News.objects.all()
for row in new_list:
print(row.title,row.summary,row.news_type.title)

 

  二 :放在一個表中的操作:choices

class News2(models.Model):
    title = models.CharField(max_length=32)
    summary = models.CharField(max_length=255)
    news_type_chices = (
        (1, '圖片'),
        (4, '挨踢1024'),
        (3, '段子'),
    )
    news_type = models.IntegerField(choices=news_type_chices)

# 查看所有新聞
new_list = News.objects.all()
for row in new_list:
print(row.title,row.summary, row.get_news_type_display() )

舉例二:用戶和用戶類型

  一:連表設計

class UserType(models.Model):
        """
        用戶類型表,個數經常變動
        """
        title = models.CharField(max_length=32)

class UserInfo(models.Model):
        """
        用戶表:講師和班主任
        """
        username = models.CharField(max_length=32)
        password = models.CharField(max_length=64)
        email = models.CharField(max_length=32)
        ut = models.ForeignKey(to="UserType")

  二:不連表設計:choices

class UserInfo(models.Model):
#     """
#     用戶表
#     """
    username = models.CharField(max_length=32)
    password = models.CharField(max_length=64)
    email = models.CharField(max_length=32,verbose_name="郵箱")
    user_type_choices = (
        (1, '班主任'),
        (2, '講師'),
    )

    user_type_id = models.IntegerField(choices=user_type_choices)

四、登錄

 可設置一個裝飾器

def auth(func):
    def inner(request,*args,**kwargs):
        is_login = request.session.get("is_login", None)
        if not is_login:
            return redirect("/login/")
        ret = func(*args,**kwargs)
        return ret
    return inner

 需要注意的:  

  1、action不寫路徑,默認提交到當前 

  2、向后台提交數據用post,獲取數據用get

  3、submit一般加上value,有些瀏覽器可能會不識別

  4、一般配置文件的鍵都是大寫的

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM