๐ค ์ฅ๊ณ ์ฟผ๋ฆฌ์ (Queryset ๊ฐ์ฒด๋ฅผ ๋ฆฌํดํ๋ ๋ฉ์๋)
์ฅ๊ณ ์ฟผ๋ฆฌ์ ์ ์ ๋ณตํด๋ณด์.
๐โโ๏ธ QuerySet API reference
ํด๋น ํํ ๋ฆฌ์ผ์ ์งํํ๋๋ฐ ์ฌ์ฉ๋๋ ๋ชจ๋ธ์ ์๋์ ๊ฐ์ด ์ ์๋๋ค.
Blog, Author, Entry 3๊ฐ์ ํ๋๋ก ๊ตฌ์ฑ๋์ด์๋ค.
class Blog(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField()
def __str__(self):
return self.name
class Author(models.Model):
name = models.CharField(max_length=200)
email = models.EmailField()
def __str__(self):
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)
number_of_comments = models.IntegerField()
number_of_pingbacks = models.IntegerField()
rating = models.IntegerField()
def __str__(self):
return self.headline
๐งช ์ฟผ๋ฆฌ์ ์ ์ธ์ ํ๊ฐ ๋๋๊ฐ?
์ฅ๊ณ ์ฟผ๋ฆฌ์
์ ๋ฐ๋ก ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฟผ๋ฆฌ๋ฌธ์ ๋ ๋ฆฌ์ง ์๋๋ค.
๋ค์๊ณผ ๊ฐ์ ์ฐ์ฐ์ ํ ๋ ์ค์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฟผ๋ฆฌ๋ฌธ์ ๋ ๋ฆฌ๊ฒ ๋๋ค.
- Iteration
- Slicing
- Pickling/ Cashing
- repr()
- len()
- list()
- bool()
๐ฝ Queryset API
๐ Queryset ๊ฐ์ฒด๋ฅผ ๋ฆฌํดํ๋ ๋ฉ์๋
filter()
- filter(**kwargs)
ํค์๋ ์ธ์๋ก ๋๊ฒจ์ค ์กฐ๊ฑด์ ๋ง๋ ์ฟผ๋ฆฌ์ ์ ๋ฐํํ๋ค.
In [7]: Blog.objects.filter(id=1)
Out[7]: <QuerySet [<Blog: hi>]>
์กฐ๊ฑด์ ๋๊ฐ์ง๋ฅผ ์ค์ AND ์ฐ์ฐ์ ๋ง๋ค ์ ์๋ค.
In [16]: Blog.objects.filter(id=1, name="hi")
Out[16]: <QuerySet [<Blog: hi>]>
- sql ์ฟผ๋ฆฌ๋ฌธ
mysql> select * from blogs_blog where id=1 and name="hi";
+----+------+---------+
| id | name | tagline |
+----+------+---------+
| 1 | hi | hello |
+----+------+---------+
exclude()
- exclude(**kwargs)
ํค์๋ ์ธ์๋ก ๋๊ฒจ์ค ์กฐ๊ฑด์ ๋ง์ง'์์' ์ฟผ๋ฆฌ์ ์ ๋ฐํํ๋ค.
In [10]: Blog.objects.all()
Out[10]: <QuerySet [<Blog: hi>, <Blog: hello>]>
In [12]: Blog.objects.exclude(id=1)
Out[12]: <QuerySet [<Blog: hello>]>
์กฐ๊ฑด์ ๋๊ฐ์ง๋ฅผ ์ค์ AND ์ฐ์ฐ์ ๋ง๋ค ์ ์๋ค.
In [18]: Blog.objects.exclude(id=1, name="hi")
Out[18]: <QuerySet [<Blog: hello>]>
- sql ์ฟผ๋ฆฌ๋ฌธ
mysql> select * from blogs_blog where not (id=1) and not (name="hi");
+----+-------+---------+
| id | name | tagline |
+----+-------+---------+
| 2 | hello | world |
+----+-------+---------+
annotate()
- annotate(*args, **kwargs)
.annotate()์ ๊ฐ ์ธ์๋ QuerySet์ ๊ฐ ๊ฐ์ฒด์ ์ถ๊ฐ ๋ ์ฃผ์์ด๋ค. ์ฃผ์๋ค์ ๋จ์ํ ๊ฐ, ๋ชจ๋ธ์ ํ๋์ ๋ํ ์ฐธ์กฐ, QuerySet์ ๊ฐ ๊ฐ์ฒด์ ๊ด๋ จ๋ ์ง๊ณ(averages, sums ๋ฑ)์ด๋ค.
์๋ก์ด ์์๋ฅผ ๋ฐ์ดํฐ ์ฟผ๋ฆฌ์ ์ถ๊ฐํ๊ณ ํด๋น ์์๋ฅผ ๋ฐ๋ก ์ถ๋ ฅํด๋ณผ ์ ์๋๋ก ํด์ฃผ๋ ๊ฒ์ธ๋ฐ, ๋ฐ์ดํฐ๊ฐ ๋ช ๊ฐ ์กด์ฌํ๋์ง๋ฅผ .count()๋ผ๋ ํจ์๋ฅผ ์ด์ฉํด์ annotateํด์ฃผ๊ณ ์ด๋ฅผ __count๋ก ์ ๊ทผํ ์ ์๋ค.
์ฝ๊ฒ ๋งํด์ .annotate()๋ ํ๋ ํ๋๋ฅผ ๋ง๋ค๊ณ ๊ฑฐ๊ธฐ์ '์ด๋ค ๋ด์ฉ' ์ ์ฑ์ฐ๊ฒ ๋ง๋๋ ๊ฒ์ด๋ค. ์์
์์ ์ปฌ๋ผ ํ๋๋ฅผ ๋ง๋๋ ๊ฒ๊ณผ ๊ฐ๋ค๊ณ ๋ณด๋ฉด ๋๋ค. ๋ด์ฉ์๋ 1. ๋ค๋ฅธ ํ๋์ ๊ฐ์ ๊ทธ๋๋ก ๋ณต์ฌํ๊ฑฐ๋, 2. ๋ค๋ฅธ ํ๋์ ๊ฐ๋ค์ ์กฐํฉํ ๊ฐ์ ๋ฃ์ ์ ์๋ค.
์ถ์ฒ
์ถ๊ฐ ์ฌ์ฉ๋ฒ ์ ๋ฆฌ ๋งํฌ: ์ด๋ ธํ ์ดํธ ๊ธฐ๋ฅ
sql์ GroupBy ๊ธฐ๋ฅ๊ณผ ๊ฐ๋ค๊ณ ์๊ฐํ๋ฉด ๋๋ค.
order_by()
- order_by(*fields)
์ฟผ๋ฆฌ์ ์ oreder_by๋ฉ์๋์ ์ธ์๋ก ๋ฃ์ด์ค ํ๋๋ฅผ ๊ธฐ์ค์ผ๋ก ์ ๋ ฌํ๋ค.
In [35]: Blog.objects.all()
Out[35]: <QuerySet [<Blog: hi>, <Blog: hello>, <Blog: bro>, <Blog: why?>]>
In [33]: Blog.objects.all().order_by('id')
Out[33]: <QuerySet [<Blog: hi>, <Blog: hello>, <Blog: bro>, <Blog: why?>]>
In [34]: Blog.objects.all().order_by('-id')
Out[34]: <QuerySet [<Blog: why?>, <Blog: bro>, <Blog: hello>, <Blog: hi>]>
order_by('ํ๋'): ์ค๋ฆ์ฐจ์
order_by('-ํ๋'): ๋ด๋ฆผ์ฐจ์
- sql ์ฟผ๋ฆฌ๋ฌธ
mysql> select * from blogs_blog order by id ASC;
+----+-------+---------+
| id | name | tagline |
+----+-------+---------+
| 1 | hi | hello |
| 2 | hello | world |
| 3 | bro | hello |
| 4 | why? | hello |
+----+-------+---------+
mysql> select * from blogs_blog order by id DESC;
+----+-------+---------+
| id | name | tagline |
+----+-------+---------+
| 4 | why? | hello |
| 3 | bro | hello |
| 2 | hello | world |
| 1 | hi | hello |
+----+-------+---------+
values()
- values(*fields, **expressions)
์ฟผ๋ฆฌ์ ๊ฒฐ๊ณผ๋ฅผ ๋์ ๋๋ฆฌ ํํ๋ก ๋ฐํํฉ๋๋ค.
In [63]: a
Out[63]: <QuerySet [{'id': 1, 'name': 'hi', 'tagline': 'hello'}, {'id': 2, 'name': 'hello', 'tagline': 'world'}, {'id': 3, 'name': 'bro', 'tagline': 'hello'}, {'id': 4, 'name': 'why?', 'tagline': 'hello'}, {'id': 5, 'name': 'hi', 'tagline': 'what?'}]>
In [64]: a[0]
Out[64]: {'id': 1, 'name': 'hi', 'tagline': 'hello'}
values_list()
- values_list(*fields, flat=False, named=False)
์ฟผ๋ฆฌ์ ์ ๊ฐ์ ํํ ํํ๋ก ๋ฐํํ๋ค.
In [65]: Blog.objects.all().values_list()
Out[66]: <QuerySet [(1, 'hi', 'hello'), (2, 'hello', 'world'), (3, 'bro', 'hello'), (4, 'why?', 'hello'), (5, 'hi', 'what?')]>
In [68]: Blog.objects.all().values_list('name')
Out[69]: <QuerySet [('hi',), ('hello',), ('bro',), ('why?',), ('hi',)]>
In [70]: Blog.objects.all().values_list('id','name')
Out[71]: <QuerySet [(1, 'hi'), (2, 'hello'), (3, 'bro'), (4, 'why?'), (5, 'hi')]>
union()
์ฟผ๋ฆฌ์ ์ ํฉ์น ๋ ์ฌ์ฉํ๋ค.
In [72]: a = Blog.objects.filter(id=1)
In [73]: a
Out[73]: <QuerySet [<Blog: hi>]>
In [74]: b = Blog.objects.filter(id=2)
In [75]: b
Out[75]: <QuerySet [<Blog: hello>]>
In [76]: result = a.union(b)
In [77]: result
Out[77]: <QuerySet [<Blog: hi>, <Blog: hello>]>
select_related()
- select_related(*fields)
sql์ ์กฐ์ธ๋ฌธ ์ญํ ์ ํ๋ค.
slecected_related๋ฅผ ํ์ฉํ๋ฉด ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ ๊ฒ ๊ฑด๋๋ฆฐ๋ค.
# ๋ฐ์ดํฐ ๋ฒ ์ด์ค๋ฅผ ๊ฑด๋๋ฆฐ๋ค.
e = Entry.objects.get(id=5)
# ๋ ๊ฑด๋๋ฆฐ๋ค.
b = e.blog
select_related ์ฌ์ฉ
# ๋ฐ์ดํฐ ๋ฒ ์ด์ค๋ฅผ ๊ฑด๋๋ฆฐ๋ค.
e = Entry.objects.select_related('blog').get(id=5)
# ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์๊ฑด๋๋ฆฐ๋ค.
b = e.blog
- sql ์ฟผ๋ฆฌ๋ฌธ
mysql> select b.*, e.* from blogs_blog as b join blogs_entry as e on b.id = e.id;
+----+-------+---------+----+----------+-----------------+------------+------------+--------------------+---------------------+--------+---------+
| id | name | tagline | id | headline | body_text | pub_date | mod_date | number_of_comments | number_of_pingbacks | rating | blog_id |
+----+-------+---------+----+----------+-----------------+------------+------------+--------------------+---------------------+--------+---------+
| 1 | hi | hello | 1 | lalala | ์๋
ํ์ธ์ | 2021-08-14 | 2021-08-14 | 1 | 1 | 1 | 1 |
| 2 | hello | world | 2 | lhahaha | ji hello | 2021-08-14 | 2021-08-14 | 1 | 3 | 2 | 2 |
+----+-------+---------+----+----------+-----------------+------------+------------+--------------------+---------------------+--------+---------+
2 rows in set (0.00 sec)
Author And Source
์ด ๋ฌธ์ ์ ๊ดํ์ฌ(๐ค ์ฅ๊ณ ์ฟผ๋ฆฌ์ (Queryset ๊ฐ์ฒด๋ฅผ ๋ฆฌํดํ๋ ๋ฉ์๋)), ์ฐ๋ฆฌ๋ ์ด๊ณณ์์ ๋ ๋ง์ ์๋ฃ๋ฅผ ๋ฐ๊ฒฌํ๊ณ ๋งํฌ๋ฅผ ํด๋ฆญํ์ฌ ๋ณด์๋ค https://velog.io/@sdk1926/์ฅ๊ณ -์ฟผ๋ฆฌ์ -Queryset-๊ฐ์ฒด๋ฅผ-๋ฆฌํดํ๋-๋ฉ์๋์ ์ ๊ท์: ์์์ ์ ๋ณด๊ฐ ์์์ URL์ ํฌํจ๋์ด ์์ผ๋ฉฐ ์ ์๊ถ์ ์์์ ์์ ์ ๋๋ค.
์ฐ์ํ ๊ฐ๋ฐ์ ์ฝํ ์ธ ๋ฐ๊ฒฌ์ ์ ๋ (Collection and Share based on the CC Protocol.)
์ข์ ์นํ์ด์ง ์ฆ๊ฒจ์ฐพ๊ธฐ
๊ฐ๋ฐ์ ์ฐ์ ์ฌ์ดํธ ์์ง
๊ฐ๋ฐ์๊ฐ ์์์ผ ํ ํ์ ์ฌ์ดํธ 100์ ์ถ์ฒ ์ฐ๋ฆฌ๋ ๋น์ ์ ์ํด 100๊ฐ์ ์์ฃผ ์ฌ์ฉํ๋ ๊ฐ๋ฐ์ ํ์ต ์ฌ์ดํธ๋ฅผ ์ ๋ฆฌํ์ต๋๋ค