Python-Django的filter和exclude過濾器的學習


typora-copy-images-to: pic

Python-Django學習

filter和exclude是Django的if/else

filter()表示匹配滿足要求的數據,而exclude()則表示匹配不滿足要求的數據。

需要注意的是filter()括號里面有很多的匹配選項

這里只需要在pycharm里面打入需要判斷的字符變量,然后就可以看到很多的末尾帶有

LT / GT

先來說一下lt-->less than, gt-->great than

其實就是大於和等於,注意有幾個是末尾帶有eq 的那個才是大於等於或者小於等與!

代碼實例:

def input(request):
   for i in range(1,15):
       student = Student()
       flag = random.randint(0,100)
       student.s_name = "Tony"+str(flag)+random.choice("abcdefghijklmnopqrstuvwxyz")
       student.s_age = flag
       student.s_sex = random.choice([0,1])
       student.save()
   return HttpResponse("data input scuess !")


def show(request):
   students = Student.objects.filter()
   context = {
       "students":students,
  }
   return render(request,"showDemo.html",context=context)


def delete(request):
   students = Student.objects.filter(s_sex=1)
   students.delete()
   students = Student.objects.filter()
   return render(request,"showDemo.html",context={"students":students})

這些代碼里面可以看到我們日常最長見的判斷代碼的實例!很有用的!

 

2 . 創建對象的方式

1.直接創建對象

def input(request)
   student = Student()
   flag = random.randint(0,100)
   student.s_name = "Tony"+str(flag)+random.choice("abcdefghijklmnopqrstuvwxyz")
   student.s_age = flag
   student.s_sex = random.choice([0,1])
   student.save()
   return HttpResponse("data input scuess !")

2.利用方法創建對象

def create_student(request):
   student = Student.objects.create(s_name="Qiao",s_age=22,s_sex=True)
   student.save()

前者看上去會更容易理解一些,但是后者確實更加簡單了.但是呢!第2種方法需要格外注意的是如果有字段沒有賦值那么數據庫里的數據將不會被設置為默認值,也就是說每一個字段都需要賦值才行!

注意我們也可以直接Student(s_name="xxx",s_age=xxx,s_sex="xx").但是這里的問題和上面的是一樣的,必須全部賦值好,不然就會有問題。並且絕對不可以嘗試重寫

__init__.py

來解決這個問題

 

方法

--對象方法

-可以調用對象的屬性,也可以調用類的屬性

--類的方法

-不能調用對象屬性,只能調用類的屬性

--靜態方法

-啥都不可以調用,不能獲取對象屬性

-只是寄生在這個類里面罷了!

 

原因:我們正常的創建對象的習慣是建一個類,然后直接創建對象也就是下面的代碼

class Class1:
def __init__(self,name,age):
self.name = name
self.age = age
if __name__ == "__main__":
class1 = Class1(name="xxx",age=xxx)#這里就是創建對象的方法了

在Django中我們建立了models的模型類,然后我們也可以像面向對象使用完全一樣的方法來創建這樣的一個對象。但是上面已經講過了,如果直接創建的話,如果我們沒有傳入默認值,那么代碼將會把它設置成空,並且我們也不可以使用重寫init方法來解決這個問題,這個其實算是一個bug了。那么接下來的方法就是如何解決這個問題的了!

解決方案


# Create your models here.
class Student(models.Model):
   s_name = models.CharField(max_length=20,db_column="name",unique=True)
   s_age = models.IntegerField(db_column="age")
   s_sex = models.BooleanField(max_length=2,db_column="sex")

   @classmethod
   def create_people(cls,name,age=100,sex=True):#這里創建了一個類方法
       return cls(s_name=name,s_age=age,s_sex=sex)#這里返回了一個類對象

   class Meta:
       db_table = "Student"
def create_student(request):
   student = Student.create_people("Qiaomo")#這里直接調用就可以了
   student.save()
   return HttpResponse("OK")

那么類里面的cls又是什么東西呢?

接下來的代碼好好看看!

class A(object):
   a = 'a'
   @staticmethod
   def foo1(name):
       print 'hello', name
       print A.a # 正常
       print A.foo2('mamq') # 報錯: unbound method foo2() must be called with A instance as first argument (got str instance instead)
   def foo2(self, name):
       print 'hello', name
   @classmethod
   def foo3(cls, name):
       print 'hello', name
       print A.a
       print cls().foo2(name)

@staticmethod和@classmethod都可以直接類名.方法名()來調用,那他們有什么區別呢 從它們的使用上來看, @staticmethod不需要表示自身對象的self和自身類的cls參數,就跟使用函數一樣。 @classmethod也不需要self參數,但第一個參數需要是表示自身類的cls參數。 如果在@staticmethod中要調用到這個類的一些屬性方法,只能直接類名.屬性名或類名.方法名。 而@classmethod因為持有cls參數,可以來調用類的屬性,類的方法,實例化對象等,避免硬編碼。

也就是說在classmethod中可以調用類中定義的其他方法類的屬性,但staticmethod只能通過A.a調用類的屬性,但無法通過在該函數內部調用A.foo2()。修改上面的代碼加以說明:

 

所以我們可以看到如果吧上面的代碼修改成如下的代碼:

class Student(models.Model):
    s_name = models.CharField(max_length=20,db_column="name",unique=True)
    s_age = models.IntegerField(db_column="age")
    s_sex = models.BooleanField(max_length=2,db_column="sex")

    @classmethod
    def create_people(cls,name,age=100,sex=True):
        cls_1 = cls()
        cls_1.s_name = name
        cls_1.s_age = age
        cls_1.s_sex = sex
        return cls_1
        # return cls(s_name=name,s_age=age,s_sex=sex)

    class Meta:
        db_table = "Student"

代碼的運行結果是完全相同的,我們可以看到cls就是代表了這個類自己,所以cls(里面添加的變量)其實就是賦值說需要的操作罷了!

##這樣我們在聯想一下前面的學習就知道,由於django的原因我們無法直接調用Student的init方法,但是我們卻可以使用類方法的特性:調用Student 類的默認init方法,然后為其傳值!

 

排序

order by

django這個排序和mysql的order by類似!我們可以先使用[類名.objects.all().orderby()]來實現排序,需要注意的是:

---1.不加order by默認是按照id進行排序的。

---2.order by里面是一個字符串,沒有代碼提示的需要注意。

---3.雖然沒有提示,但是可以告訴你,就是你在models里面定義的字段名。

---4.如果想要升序排序,直接filter就可以了,但如果要降序排序需要加一個"-"。

下面是演示Demo

def show(request):
    students = Student.objects.filter().order_by("-s_age")
    context = {
        "students":students,
    }
    return render(request,"showDemo.html",context=context)

2020-02-01 17-41-26屏幕截圖

values

如果我們需要調試數據或者吧數據轉換為json的話可以使用這個屬性!

[類名.objects.values]

可以拿到一個QuerySet的數據,里面有一個大列表數據,列表內部嵌套好了很多字典,每一個字典就是一個對象!這樣的數據可以比較方便轉換成為json數據庫文件

def show(request):
    students = Student.objects.filter().order_by("-s_age")
    student_value = students.values()
    for student_val in student_value:
        print(student_val)
    context = {
        "students":students,
    }
    return render(request,"showDemo.html",context=context)

返回結果:

{'s_name': 'Qiaomo', 'id': 1, 's_sex': True, 's_age': 100}
{'s_name': 'Tony98h', 'id': 8, 's_sex': False, 's_age': 98}
{'s_name': 'Tony90n', 'id': 10, 's_sex': True, 's_age': 90}
{'s_name': 'Tony80c', 'id': 9, 's_sex': True, 's_age': 80}
{'s_name': 'Tony73b', 'id': 11, 's_sex': True, 's_age': 73}
{'s_name': 'Tony71e', 'id': 3, 's_sex': True, 's_age': 71}
{'s_name': 'Tony63k', 'id': 5, 's_sex': True, 's_age': 63}
{'s_name': 'Tony57x', 'id': 13, 's_sex': False, 's_age': 57}
{'s_name': 'Tony54a', 'id': 7, 's_sex': False, 's_age': 54}
{'s_name': 'Tony53a', 'id': 12, 's_sex': True, 's_age': 53}
{'s_name': 'Tony48t', 'id': 14, 's_sex': True, 's_age': 48}
{'s_name': 'Tony35i', 'id': 2, 's_sex': True, 's_age': 35}
{'s_name': 'Tony24i', 'id': 4, 's_sex': False, 's_age': 24}
{'s_name': 'Tony22p', 'id': 6, 's_sex': True, 's_age': 22}
{'s_name': 'Tony2t', 'id': 15, 's_sex': True, 's_age': 2}

其他的方法:

first/last

objects.all().first()/objects.all().last()

--默認 是沒有上面問題的

--隱藏bug

-可能會出現first和last完全相同的對象(有可能!)

--手動寫排序算法吧!

exists

object.exists==>True/False

2020-02-01 17-56-11屏幕截圖

 

網絡服務器的報錯提示:

5xx的錯誤都是服務器崩潰了!這個很尷尬的!

其他:

2xx:請求是成功了

3xx:被轉發了

4xx:客戶端掛了

 

get的毛病

--1.如果嘗試get一個不存在的數據那么我們的程序會拋出一個500異常,

--2.如果查詢對象存在多個值的時候,他還是會拋出異常,並且異常的原因就是返回的數據超過一個了!

 

切片

--和python不太一樣

--QuerySet[5:15] #獲取第五條到第十五條數據

-相當於SQL語句中的limit和offset

-不需要優化算法了,直接就可以在數據庫里面限制好要查詢的數據了

-注意這里的切片大多數都是左閉右開的區間

 

緩存集

--filter

--exclude

--all

--都不會真正的查詢數據庫

--只有在迭代結果集或者獲取單個對象屬性的時候才會查詢數據庫

--懶查詢

查詢條件

  • 屬性__運算符=值

  • gt

  • lt

  • gte

  • lte

  • in在某一集合中

  • contains 類似於 模糊查詢like

  • startswith 以xx開始 本質也是like

  • endswith 以xx結束 也是like

  • exact 精確查詢

  • 前面添加i,忽略大小寫的匹配

    • iall

    • iget

    • istartswith

    • iendswith

    • icontains

    • .......

  • django中查詢條件有時區問題

    • 關閉Django中的自定義時區#setting -->USE_TZ=False即可

    • 在數據庫中創建對應的時區表


免責聲明!

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



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