django 表操做

添加表紀錄

# Create your models here.
class Book(models.Model):
    id = models.AutoField(primary_key=True)
    title = models.CharField(max_length=32)
    state = models.BooleanField()
    pub_date = models.DateField()
    price = models.DecimalField(max_digits=8, decimal_places=2)
    publish = models.CharField(max_length=32)

方式1

    book_obj = models.Book(title='python web',price=29, publish='北京出版社',pub_date="2012-12-12")
    book_obj.save()

方式2

  book_obj = models.Book.objects.create(title="java紅寶書", state=True, price=100, publish="蘋果出版社", pub_date="2012-12-12")

刪除表紀錄

刪除方法就是 delete()。它運行時當即刪除對象而不返回任何值。例如:java

model_obj.delete()

 按條件刪除

 ret = models.Book.objects.all().filter(price__in=[100, 88]).delete()

 級聯刪除

在 Django 刪除對象時,會模仿 SQL 約束 ON DELETE CASCADE 的行爲,換句話說,刪除一個對象時也會刪除與它相關聯的外鍵對象。例如:python

class Blog(models.Model):
    name = models.CharField(max_length=100)
    tagline = models.TextField()

    def __str__(self):              # __unicode__ on Python 2
        return self.name

class Author(models.Model):
    name = models.CharField(max_length=200)
    email = models.EmailField()

    def __str__(self):              # __unicode__ on Python 2
        return self.name

class Entry(models.Model):
    blog = models.ForeignKey(Blog, on_delete=models.CASCADE)
    headline = models.CharField(max_length=255)
    body_text = models.TextField()
    pub_date = models.DateField()
    mod_date = models.DateField()
    authors = models.ManyToManyField(Author)
    n_comments = models.IntegerField()
    n_pingbacks = models.IntegerField()
    rating = models.IntegerField()

    def __str__(self):              # __unicode__ on Python 2
        return self.headline

deletegit

b = Blog.objects.get(pk=1)
# This will delete the Blog and all of its Entry objects.
b.delete()

要注意的是: delete() 方法是 QuerySet 上的方法,但並不適用於 Manager 自己。這是一種保護機制,是爲了不意外地調用 Entry.objects.delete() 方法致使 全部的 記錄被誤刪除。若是你確認要刪除全部的對象,那麼你必須顯式地調用:web

Entry.objects.all().delete()  

若是不想級聯刪除,能夠設置爲:sql

blog = models.ForeignKey(Blog, on_delete=models.SET_NULL, blank=True, null=True)

刪除語句數據庫

Blog.objects.all().filter(name='python_qq').delete()

修改表紀錄

Book.objects.filter(title__startswith="py").update(price=120)

 update()方法對於任何結果集(QuerySet)均有效,這意味着你能夠同時更新多條記錄update()方法會返回一個整型數值,表示受影響的記錄條數。django

 

查詢表記錄

查詢API

1> all():                  查詢全部結果
  
<2> filter(**kwargs):       它包含了與所給篩選條件相匹配的對象
  
<3> get(**kwargs):          返回與所給篩選條件相匹配的對象,返回結果有且只有一個,
                            若是符合篩選條件的對象超過一個或者沒有都會拋出錯誤。
  
<4> exclude(**kwargs):      它包含了與所給篩選條件不匹配的對象
 
<5> order_by(*field):       對查詢結果排序
  
<6> reverse():              對查詢結果反向排序
  
<8> count():                返回數據庫中匹配查詢(QuerySet)的對象數量。
  
<9> first():                返回第一條記錄
  
<10> last():                返回最後一條記錄
  
<11> exists():              若是QuerySet包含數據,就返回True,不然返回False
 
<12> values(*field):        返回一個ValueQuerySet——一個特殊的QuerySet,運行後獲得的並非一系列
                            model的實例化對象,而是一個可迭代的字典序列
<13> values_list(*field):   它與values()很是類似,它返回的是一個元組序列,values返回的是一個字典序列
 
<14> distinct():            從返回結果中剔除重複紀錄

基於雙下劃線的模糊查詢  

Book.objects.filter(price__in=[100,200,300])
Book.objects.filter(price__gt=100)
Book.objects.filter(price__lt=100)
Book.objects.filter(price__range=[100,200])
Book.objects.filter(title__contains="python")
Book.objects.filter(title__icontains="python")
Book.objects.filter(title__startswith="py")
Book.objects.filter(pub_date__year=2012)
Entry.objects.get(headline__contains='Lennon')

contains:後端

表示包含的意思!大小寫敏感!app

icontains:函數

contains的大小寫不敏感模式。

startswith和endswith

以什麼開頭和以什麼結尾。大小寫敏感!

istartswith和iendswith

是不區分大小寫的模式。

查詢操做練習

    # 1
    # 查詢老男孩出版社出版過的價格大於200的書籍

    book_list = models.Book.objects.filter(price__gt=200, publish='老男孩出版社')
    print(book_list)
    # 2
    # 查詢2017年8月出版的全部以py開頭的書籍名稱
    book_list = models.Book.objects.filter(title__startswith='py', pub_date__year=2017,pub_date__month=8)
    print(book_list)
    # 3
    # 查詢價格爲50, 100
    # 或者150的全部書籍名稱及其出版社名稱
    book_list = models.Book.objects.filter(price__in=[50, 100,150]).values_list('publish','title')
    print(book_list)
    # 4
    # 查詢價格在100到200之間的全部書籍名稱及其價格
    book_list = models.Book.objects.filter(price__range=[100,200]).values_list('title','price')
    print(book_list)
    # 5
    # 查詢全部人民出版社出版的書籍的價格(從高到低排序,去重)
    book_list = models.Book.objects.filter(publish='人民出版社').values_list('price').distinct().order_by('-price')
    print(book_list)

  

多表操做

class Author(models.Model):
    nid = models.AutoField(primary_key=True)
    name=models.CharField( max_length=32)
    age=models.IntegerField()

    # 與AuthorDetail創建一對一的關係
    authorDetail=models.OneToOneField(to="AuthorDetail",on_delete=models.CASCADE)


class AuthorDetail(models.Model):

    nid = models.AutoField(primary_key=True)
    birthday=models.DateField()
    telephone=models.BigIntegerField()
    addr=models.CharField( max_length=64)

class Publish(models.Model):
    nid = models.AutoField(primary_key=True)
    name=models.CharField( max_length=32)
    city=models.CharField( max_length=32)
    email=models.EmailField()


class Book(models.Model):

    nid = models.AutoField(primary_key=True)
    title = models.CharField( max_length=32)
    publishDate=models.DateField()
    price=models.DecimalField(max_digits=5,decimal_places=2)

    # 與Publish創建一對多的關係,外鍵字段創建在多的一方
    publish=models.ForeignKey(to="Publish",to_field="nid",on_delete=models.CASCADE)
    # 與Author表創建多對多的關係,ManyToManyField能夠建在兩個模型中的任意一個,自動建立第三張表
    authors=models.ManyToManyField(to='Author',)

 

多對多添加方式

    book_obj = Book.objects.filter(nid=1).first()
    alex = Author.objects.create(name='alex', age='20', authorDetail_id=1)
    egon = Author.objects.create(name='egon', age='18', authorDetail_id=2)
    #
    # # 多對多添加方式
    book_obj.authors.add(alex, egon)

跨表查詢

 # 1.基於對象的查詢(子查詢)
    """
    A-B
    關聯屬性在A表

    正向查詢 A---------B
    反向查詢 B---------A
    """
    """
    一對多
    """

    # 正向查詢查字段
    # 查詢書名爲紅樓夢的出版社名字
    book_obj = Book.objects.filter(title='紅樓夢').first()
    print(book_obj.publish.name)  # 查詢關聯的出版社對象

    # 反向查詢查表名_set.all
    # 查詢書名爲人民出版社的書名
    publish_obj = Publish.objects.filter(name='人民出版社').first()
    print(publish_obj.book_set.all())

    """
    多對多

    """
    # 正向查詢查字段
    # 查詢書名爲紅樓夢的做者名字
    book_obj = Book.objects.filter(title='紅樓夢').first()
    print(book_obj.authors.all())  # 查詢關聯的做者對象

    # 反向查詢查表名_set.all
    # 查詢alex寫的書名
    author_obj = Author.objects.filter(name='alex').first()
    print(author_obj.book_set.all())

    """
    一對一查詢
    """
    """
    A - B
    關聯屬性在A表

    正向查詢
    A - --------B
    反向查詢
    B - --------A

     """

    # 正向查詢查字段
    # 查詢alex做者電話
    author_obj = Author.objects.filter(name='alex').first()
    print(author_obj.authorDetail.telephone)  # 查詢關聯的做者細節對象

    # 反向查詢查表名
    # 查詢電話111的做者
    authorDetail_obj = AuthorDetail.objects.filter(telephone='111').first()
    print(authorDetail_obj.author.name, authorDetail_obj.author.age)

 

 # 2.基於雙下劃線的查詢(join)
    # 正向查詢查字段,反向查詢查表名告訴orm join

    # 查詢書名爲紅樓夢的出版社名字(一對多)
    """
    sql:
    select app3_publish.name from app3_book inner join app3_publish
    on app3_book.publish_id = app3_publish.nid where app3_book.title='紅樓夢'

    """
    # 方式一
    # <QuerySet [{'publish__name': '人民出版社'}]>
    print(Book.objects.filter(title='紅樓夢').values("publish__name"))

    # 方式二
    print(Publish.objects.filter(book__title='紅樓夢').values(
        "name"))  # <QuerySet [{'publish__name': '人民出版社'}]>

    # 查詢書名爲紅樓夢的做者名字(多對多)
    """
    sql:
    select name from app3_author inner join app3_book_authors on app3_author.nid = app3_book_authors.author_id
    inner join app3_book on app3_book.nid = app3_book_authors.book_id
    """
    # 方式一
    # <QuerySet [{'authors__name': 'alex,egon'}]>
    print(Book.objects.filter(title='紅樓夢').values("authors__name"))

    # 方式二
    print(Author.objects.filter(book__title='紅樓夢').values("name"))

    # 查詢alex做者電話
    print(Author.objects.filter(name='alex').values("authorDetail__telephone"))

    print(AuthorDetail.objects.filter(author__name='alex').values("telephone"))

    # 進階練習
    # 查詢電話111做者出版過全部書籍及書籍出版社的名稱

    # 方式1
    print(
        Book.objects.filter(
            authors__authorDetail__telephone__startswith='11').values(
            "title",
            "publish__name"))

    # 方式2
    print(
        Author.objects.filter(
            authorDetail__telephone__startswith='11').values(
            "book__title",
            "book__publish__name"))

  

聚合查詢

from django.db.models import Count, Max, Min, Avg

    print(
        Book.objects.all().aggregate(
            avg_price=Avg("price"),
            max_price=Max('price'),
            min_price=Min('price')))  # 返回字典

    # 單表分組查詢
    # 查詢每個省以及對應的員工數

    # emp:
    print(Emp.objects.values("province").annotate(cnt=Count("id")))

    # 多表分組查詢
    # 查詢出版社的名稱及出版書籍的個數
    ret = Publish.objects.values("nid").annotate(cnt=Count("book__title"))
    print(ret)

    ret = Publish.objects.values("name").annotate(cnt=Count("book__title"))
    print(ret)

    ret = Publish.objects.values("name").annotate(
        cnt=Count("book__title")).values(
        "name", "cnt")
    print(ret)

    # 查詢每個做者的名字以及出版書籍的最高價格
    ret = Author.objects.values("pk").annotate(
        max_price=Max("book__price")).values(
        "name", "max_price")
    print(ret)

    # 查詢每個書籍的名稱及對應的做者個數
    ret = Book.objects.values("pk").annotate(
        cnt=Count("authors__nid")).values(
        "title", "cnt")
    print(ret)

    # 統計每一本以py開頭的書籍的做者個數:
    ret = Book.objects.filter(
        title__startswith="py").values("pk").annotate(
        cnt=Count("authors__nid")).values(
            "title",
        "cnt")
    print(ret)

    # (4)統計不止一個做者的圖書
    ret = Book.objects.values("pk").annotate(
        cnt=Count("authors__nid")).filter(
        cnt__gt=1).values(
            "title",
        "cnt")
    print(ret)

    # F查詢Q查詢
    from django.db.models import F, Q
    # 統計書的評論數大於讀過數
    ret = Book.objects.filter(comment_num__lt=F("read_num"))
    print(ret)

    Book.objects.all().update(price=F("price") + 10)

    ret = Book.objects.filter(Q(title='紅樓夢') | Q(price__gt=100))
    print(ret)

    ret = Book.objects.filter(~Q(title='紅樓夢') | Q(price__gt=100))
    print(ret)

 

操做API

get() 獲取單個對象
create() 建立對象,無需save()
get_or_create() 查詢對象,若是沒有找到就新建對象
update_or_create() 更新對象,若是沒有找到就建立對象
bulk_create() 批量建立對象
count() 統計對象的個數
in_bulk() 根據主鍵值的列表,批量返回對象
iterator() 獲取包含對象的迭代器
latest() 獲取最近的對象
earliest() 獲取最先的對象
first() 獲取第一個對象
last() 獲取最後一個對象
aggregate() 聚合操做
exists() 判斷queryset中是否有對象
update() 批量更新對象
delete() 批量刪除對象

 

 get()

get(**kwargs)

返回按照查詢參數匹配到的單個對象,參數的格式應該符合Field lookups的要求。

若是匹配到的對象個數不僅一個的話,觸發MultipleObjectsReturned異常

若是根據給出的參數匹配不到對象的話,觸發DoesNotExist異常。例如:

 

bulk_create()

bulk_create(objs, batch_size=None)

以高效的方式(一般只有1個查詢,不管有多少對象)將提供的對象列表插入到數據庫中:

Entry.objects.bulk_create([
...     Entry(headline='This is a test'),
...     Entry(headline='This is only a test'),
... ])

注意事項:

  • 不會調用模型的save()方法,而且不會發送pre_savepost_save信號。
  • 不適用於多表繼承場景中的子模型。
  • 若是模型的主鍵是AutoField,則不會像save()那樣檢索並設置主鍵屬性,除非數據庫後端支持。
  • 不適用於多對多關係。

batch_size參數控制在單個查詢中建立的對象數。

 

count()

返回在數據庫中對應的QuerySet對象的個數。count()永遠不會引起異常。

 

latest(field_name=None)

使用日期字段field_name,按日期返回最新對象。

下例根據Entry的'pub_date'字段返回最新發布的entry:

Entry.objects.latest('pub_date')

exists()

若是QuerySet包含任何結果,則返回True,不然返回False。

查找具備惟一性字段(例如primary_key)的模型是否在一個QuerySet中的最高效的方法是:

entry = Entry.objects.get(pk=123)
if some_queryset.filter(pk=entry.pk).exists():
    print("Entry contained in queryset")

它將比下面的方法快不少,這個方法要求對QuerySet求值並迭代整個QuerySet:

if entry in some_queryset:
   print("Entry contained in QuerySet")

若要查找一個QuerySet是否包含任何元素:

if some_queryset.exists():
    print("There is at least one object in some_queryset")

將快於:

if some_queryset:
    print("There is at least one object in some_queryset")

查詢參數及聚合函數

http://www.liujiangblog.com/course/django/132

相關文章
相關標籤/搜索