Open 9health opened 1 year ago
Hi Hải, @9health
Đây là 1 phần trong việc hiểu và áp dụng Chương 5 phải không Hải ?
Các task nhiều và loạn quá, Hải gom nhóm kết quả một vài output để tớ cho vào taiga theo dõi theo từng sprint nhé
BR Quang
Hello @quangvv9Life,
Trước hết sorry Quang rất nhiều vì hôm qua tớ có làm 1 giờ thôi chứ không có hơn được ấy :(
Nay thì tớ đang ở quê, cũng không biết có join họp được hay không nữa :(.
Nhà bà ngoại tớ thì chưa dọn dẹp gì, nhà dì tớ cũng thế :(. Hix
Qua thì tớ dậy lúc tầm 7 giờ hơn và ngồi tới 8 giờ hơn thì ăn sáng.
Sau đấy tớ ngồi thử nghĩ ra cách viết cái Ghi Nhận Cảm Xúc nhanh hơn.
Có lẽ là dùng file Word là nhanh hơn PowerPoint hix.
Viết ý theo kiểu gạch đầu dòng và ngắn thôi nữa :(
Viết ý lớn trước, ý nhỏ sau chứ không sa đà vào chi tiết :(.
Chiều thì 14h30 mẹ tớ về quê, tớ đòi về cùng :(.
Về đến nơi thì tớ ngồi viết email cho bạn ĐH tới tận tối @@. Bạn ĐH khác lâu lắm không liên lạc rồi...
Rồi tối cũng chả làm gì được :(
Sáng nay định dậy sớm mà cũng không dậy được hix :(
Sorry Quang
Hôm trước đến nhà Quang thấy Quang demo dùng Python Django shell để thử database model mà lúc ý tớ cũng chưa nghĩ ra gì.
Cơ mà về nhà tớ bắt đầu suy nghĩ dần tới cái task học QuerySet trong Python Django và thấy là cái của Quang demo có lẽ rất hợp với cái task đấy @@.
Chỉ cần mở 1 dòng gọi cái interpreter đấy ra và import là mình có được tất cả thư viện Python Django trong đấy rồi và làm gì cũng được hết!!!
Quả thật là hay ho đấy, tớ thấy nó giống như là học SQL vào đấy gõ các lệnh và dần dần quen vậy!!!
Đúng là dùng shell cách tiếp cận ban đầu nhanh hơn được chứ file thì nó hơi bị kiểu như gò bó quá!!!
Đây là cách tớ gọi interactive shell của Python Django ra
(venv_3.6.9) ninehealth@LinuxVM15:~/work/moviegeek$ python3 manage.py shell
>>> from collector.models import Log
Tớ thử import cái database model của collector apps và không có vấn đề gì!!!
Nếu mà gọi lệnh python3
như bình thường đảm bảo sẽ bảo error hix.
>>> help(Log.objects)
Help on Manager in module django.db.models.manager object:
class Manager(BaseManagerFromQuerySet)
| Method resolution order:
| Manager
| BaseManagerFromQuerySet
| BaseManager
| builtins.object
|
| Data and other attributes defined here:
|
| __slotnames__ = []
|
| ----------------------------------------------------------------------
| Methods inherited from BaseManagerFromQuerySet:
|
| aggregate(self, *args, **kwargs)
| Return a dictionary containing the calculations (aggregation)
| over the current queryset.
Tiếp đó tớ thử dùng lệnh help()
trong Python Django shell xem có cái gì hay ho hiện ra không.
Lệnh này tớ học được ở khóa học Python trên Google University hồi trước năm 2011 thì phải. Vậy là hơn chục năm rùi :(.
Khóa học đấy hay thật, mọi thứ đều rất là đơn giản và dễ hiểu lại còn thực tế nữa.
Mỗi tội là tớ chỉ biết học theo thôi chứ áp dụng chắc là ít =.=
Như Quang nhìn thấy ở trên thì có thể thấy là Log.objects
là 1 object được instantiate được từ Manager
class.
Manager
class đấy là từ module django.db.models.manager
của Python Django.
Sorry Quang nếu có gì tớ giải thích sai nhé vì khái niệm này có vẻ tớ ít dùng nên dễ bị nhầm lẫn :(. Tớ chỉ thuộc lý thuyết thôi. Hi vọng là tương lai sẽ cải thiện hơn hix hix.
Class Manager
này được kế thừa từ class BaseManagerFromQuerySet
.
Class BaseManagerFromQuerySet
được kế thừa từ class BaseManager
.
Class BaseManager
được kế thừa từ class builtins.object
.
Và nếu 1 methods (hàm) trong class Manager
mà không tìm thấy ở class kế thừa level trên rồi level trên trên nữa!!!
Trong class này cũng chả thấy members (các biến) có gì cả, chỉ thấy có mỗi __slotnames__
>>> help(Log)
Help on class Log in module collector.models:
class Log(django.db.models.base.Model)
| Log(id, created, user_id, content_id, event, session_id)
|
| Method resolution order:
| Log
| django.db.models.base.Model
| builtins.object
|
| Methods defined here:
|
| __str__(self)
| Return str(self).
|
| content_id = <django.db.models.query_utils.DeferredAttribute object>
| created = <django.db.models.query_utils.DeferredAttribute object>
| event = <django.db.models.query_utils.DeferredAttribute object>
| get_next_by_created = _method(self, *, field=<django.db.models.fields.DateTimeField: created>, is_next=True, **kwargs)
Tương tự như thế tớ xem thử phần Help cho Log
class.
Như collector app ở đây được gọi là Python module.
Python module sẽ bao gồm nhiều class ở trong đấy...
Dùng Python module sẽ làm cho việc quản lý nhiều class đễ hơn :|.
Có cái gì đó tớ thấy nó khác khác giữa Log
và Log.objects
Thôi tìm hiểu sau vậy :(
Dùng cách trên thì tương tự có thể xem class Log
đấy
| ----------------------------------------------------------------------
| Methods inherited from BaseManager:
|
| __eq__(self, other)
| Return self==value.
|
| __hash__(self)
| Return hash(self).
|
| __init__(self)
| Initialize self. See help(type(self)) for accurate signature.
|
| __str__(self)
| Return "app_label.model_label.manager_name".
|
| all(self)
|
| check(self, **kwargs)
|
| contribute_to_class(self, model, name)
Đây là các hàm trong Log.objects
kế thừa được từ class Base Manager
.
| Data and other attributes defined here:
|
| DoesNotExist = <class 'collector.models.Log.DoesNotExist'>
| The requested object does not exist
|
| MultipleObjectsReturned = <class 'collector.models.Log.MultipleObjects...
| The query returned multiple objects when only one was expected.
|
| objects = <django.db.models.manager.Manager object>
Đây là phần data (các biến hay variables) trong Log
class
Như Quang thấy có thể thấy objects
là 1 member trong class Log
.
Help on class Log in module collector.models:
class Log(django.db.models.base.Model)
| Log(id, created, user_id, content_id, event, session_id)
|
| Method resolution order:
| Log
| django.db.models.base.Model
| builtins.object
|
| Methods defined here:
| ----------------------------------------------------------------------
| Data and other attributes defined here:
| ----------------------------------------------------------------------
| Methods inherited from django.db.models.base.Model:
| ----------------------------------------------------------------------
| Class methods inherited from django.db.models.base.Model:
| ----------------------------------------------------------------------
| Data descriptors inherited from django.db.models.base.Model:
| ----------------------------------------------------------------------
Đây là tớ copy ra những mục chính ở phần help của class Log
Python rất là dễ hiểu luôn.
Phần help mà tự động generate ra quả là hay ho đấy.
Và truy cập vào cũng rất là dễ luôn!!!
Tuy là không có hình về các class quan hệ với nhau thế nào nhưng mà tương lai khi đọc nhiều rồi mình có thể hình dung được ở trong đầu ý!!1
Hi vọng là như thế!!!
Kiến thức sẽ tăng lên dần!!!
Help on Manager in module django.db.models.manager object:
class Manager(BaseManagerFromQuerySet)
| Method resolution order:
| Manager
| BaseManagerFromQuerySet
| BaseManager
| builtins.object
|
| Data and other attributes defined here:
| ----------------------------------------------------------------------
| Methods inherited from BaseManagerFromQuerySet:
| ----------------------------------------------------------------------
| Methods inherited from BaseManager:
| ----------------------------------------------------------------------
| Class methods inherited from BaseManager:
| ----------------------------------------------------------------------
| Static methods inherited from BaseManager:
| ----------------------------------------------------------------------
| Data descriptors inherited from BaseManager:
| ----------------------------------------------------------------------
| Data and other attributes inherited from BaseManager:
Còn đây là tớ copy lại các mục chính trong phần Help của Log.objects
https://en.wikibooks.org/wiki/Python_Programming/Self_Help
https://docs.python.org/3/tutorial/interpreter.html
Tớ thấy phần Help của Python hay quá và lên mạng xem là có tính năng gì nữa không
>>> help("django")
Help on package django:
NAME
django
PACKAGE CONTENTS
__main__
apps (package)
conf (package)
contrib (package)
core (package)
db (package)
dispatch (package)
forms (package)
http (package)
middleware (package)
shortcuts
Như ở trên thì có thể thấy nội dung của Python Django package.
Lại 1 khái niệm mới nữa xuất hiện ở đây là package!!!
Có lẽ package sẽ là 1 tập hợp của nhiều module trong Python.
Kiến thức của tớ có vẻ bị rỗng hay quên nhiều quá!!!
Có lẽ sẽ cần bổ sung thêm hix.
Cơ mà công nhận là phần Help trong Python interpreter quả là hay vì đọc kiểu này có thể cũng hiểu sơ sơ rồi, list ra các hàm mình có thể dùng rồi thay vì lên mạng search và vào web lung tung, có khi lại còn bị giải thích sai nữa ý @_@.
Hix tới đây thì tớ bị gọi đi ăn sáng hôm qua rồi
Mong Quang thông cảm nhé :( Tớ cũng chưa biết recover cái 1 tiếng đấy thế nào đây huhu.
Lý do tớ phải tìm hiểu kỹ thế này thay vì lên mang xem QuerySet người ta viết như thế nào và bắt chước là để hiểu sâu hơn mình có thể làm gì với QuerySet!!!
Không thể chỉ có lên mạng và đọc tài liệu mãi được mà cần nhìn vào source code hoặc documentation để dùng =.=
Mà documentation của Django tớ thấy viết cứ ảo ảo thế nào ấy =.= Chắc do tớ còn non nên chưa quen =.=
Mà tớ thấy kiểu xem Help bằng command line thế này hay hơn nhiều so với dùng chuột như ở Visual Studio các thứ hay lên trang Microsoft Docs =.=
Do intepreter tiện mà!!!
Visual Studio tớ nghĩ cũng có khả năng hiển thị tài liệu như Python thôi cơ mà nó nhiều và nhìn choáng quá =.=
Còn nếu mà dùng auto-complete hay IntelliSense của Microsoft để gợi ý thì nói thật là mình cũng không hiểu các hàm ý làm gì :(.
Xong rồi click vào ra 1 cái document to đùng :(. Ngại thật!!!
Vậy nên hi vọng Quang chấp nhận cách tìm hiểu này của tớ nhé @@@@@. Cho dù nó hơi miên man thật cơ mà sẽ hiểu sâu hơn và debug có lẽ sẽ tốt hơn :(.
Dù gì cũng khá mới với tớ vì tớ cũng toàn theo kiểu dùng thư viện Python trong 1 file thôi chứ có bao giờ viết Python ở nhiều file đâu :(.
Cũng chỉ xem ví dụ trên mạng và gọi hàm đấy ra thui!!!
Cơ mà tớ nghĩ tiếp cận kiểu này thì mới có thể dùng hết chức năng của Python Django được.
Và còn hiểu về OOP trong Python nữa, quả là hay ho!!!
Ngoài ra thì tớ cũng nghĩ về buổi họp với Microsoft hôm trước ở nhà Quang với ở quán cafe.
Đúng là khi mình ngồi làm việc, có bàn làm việc, chuẩn bị tư thế vào đấy họp trước 15 phút thì mọi thứ mới smooth được, tài liệu mới ghi chép đầy đủ được :(.
Chứ như hôm ở chỗ chị Nhi tớ với Quang chả ghi lại gì, chả chụp lại màn hình gì :(. Cũng phí thật.
Thôi rút kinh nghiệm hix hix T_T. Hi vọng là tuần sau là tuần thứ 3 từ hôm họp, Quang gửi 1 cái email remind lý do đấy và họ sẽ share lại cho mình cái video =.=
Hoặc là nếu thấy audio và ảnh tớ capture là đủ rồi thì thôi vậy!!!
Cảm ơn Quang một lần nữa!!!
Có gì tớ sẽ xem meeting minute của Quang và anh Công sau.
Nếu Quang muốn làm theo kiểu cứ insert dần slide vào thì cứ làm nhé!!!
Cơ mà có thể làm theo kiểu mỗi lần họp copy file cũ ra 1 file mới ý được không mặc dù OneDrive cũng cho lưu version T_T.
Cảm ơn Quang nhiều!!!
Chúc Quang cuối tuần vui vẻ và họp thật tốt!!!
À qua thì tớ phát hiện ra 1 lỗi chưa setup đúng Python Virtual Environments nữa. Có lẽ là Quang cũng đã phát hiện ra và fix lại được rồi!!!
Thôi tớ thấy mọi thứ với tớ vẫn đang kiểu còn okay nên tớ sẽ để pending tạm thời hix.
Hello @quangvv9Life,
Thanks Quang đã chờ đợi nhé @@.
Tớ có đọc lướt qua comment trên của Quang cơ mà chưa kỹ lắm.
Có gì tớ sẽ trả lời sau nhé.
Tớ vừa mới phơi quần áo xong :(.
Sorry tớ comment hơi muộn.
Qua thì tớ về quê rồi. Sáng thì lúc Quang gọi họp tớ cũng ăn sáng xong rồi cơ mà đang ở nhà dì với cả em họ đang ngủ nên là thôi :( Tớ quay vào đọc QuerySet tiếp :(.
Chiều ngủ dậy thì mẹ tớ bắt tớ ngồi làm bài tập chị kia và kêu là tốn bao nhiêu xiền 1 buổi @@. Cơ mà thôi tớ lại đọc tiếp QuerySet từ 4 giờ chiều tới 6 giờ 30 chiều.
Hình như tớ ngồi không đúng tư thế cái bàn học gấp nên tối bị đau cổ @@. Mệt quá thui chả làm gì nữa.
Tớ ngồi xem thử file The Oxford 3000 xem là mình biết bao nhiêu từ trong ý (chị kia thì nghe bảo muốn học PhD cần tiếng Anh cơ mà tớ hỏi vài từ trong này mà cũng không biết hết @@, sợ thật mà dịch tiếng Việt qua Google Translate vẫn ổn lắm...)
Chắc 30 phút mới kiểm tra xong thì thấy là mình không biết có 15 từ @@.
Ngẫm nghĩ lại không hiểu mình học 3,000 từ dấy kiểu gì vậy @@. Nói thật hình như tớ cũng ít tự học tiếng Anh lắm =.=
Thôi hôm nào thử file 5,000 từ xem biết được bao nhiêu từ :|. Tạm thời mình đang là Upper-Intermediate rùi...
Sáng dậy thì tớ ngồi lau cửa kính cho nhà dì tớ @@. Sợ thật lau tới 12 giờ trưa mà chưa xong cơ mà mẹ gọi ăn cơm với hái khế nên là T_T.
Chiều thì 2 giờ tớ với mẹ đi xe buýt về nhà. 4 giờ về tới nhà.
Tớ ngồi học tiếp cái QuerySet từ lúc 5 giờ 30 tới 7 giờ tối :-?
Ăn cơm xong lại ngồi vào học tiếp cái QuerySet từ 8 giờ 30 tối tới 9 giờ 30 tối rồi mẹ nhờ gõ văn bản.
Tổng cộng hôm qua thì 4 tiếng. Hôm nay thì 2 tiếng cho cái QuerySet này @@.
Hao thời gian phết nhưng mà vui @@.
Giờ chắc tớ sẽ chả cần mở SQLite3 ra để xem database có gì nữa mà sẽ python3 manage.py shell
rồi dùng lệnh import collector
help(collector.models)
để từ đấy xem các biến có gì :|.
Thanks Quang nhiều về lệnh gọi cái shell kia hix. Cái shell ý giúp tớ tăng productivity lên nhiều lắm vì nói thật tớ thích dùng intepreter hơn là cứ viết file, sửa, save rồi compile, run @@.
Okay tiếp tục tìm hiểu thêm về Python Django shell nào.
help
>>> help(help)
Help on _Helper in module _sitebuiltins object:
class _Helper(builtins.object)
| Define the builtin 'help'.
|
| This is a wrapper around pydoc.help that provides a helpful message
| when 'help' is typed at the Python interactive prompt.
|
| Calling help() at the Python prompt starts an interactive help session.
| Calling help(thing) prints help for the python object 'thing'.
|
| Methods defined here:
|
| __call__(self, *args, **kwds)
| Call self as a function.
Cách sử dụng hàm help
trong Python intepreter.
i = 1
>>> help(int)
Help on int object:
class int(object)
| int(x=0) -> integer
| int(x, base=10) -> integer
|
| Convert a number or string to an integer, or return 0 if no arguments
| are given. If x is a number, return x.__int__(). For floating point
| numbers, this truncates towards zero.
|
| __add__(self, value, /)
| Return self+value.
|
| __and__(self, value, /)
| Return self&value.
|
| __bool__(self, /)
| self != 0
|
| __ceil__(...)
| Ceiling of an Integral returns itself.
|
| __divmod__(self, value, /)
| Return divmod(self, value).
|
| __eq__(self, value, /)
| Return self==value.
|
| __float__(self, /)
| float(self)
Xem các hàm có sẵn của int
class. Rất là hay ho luôn, nếu quên có thể vào đấy tham khảo O_O.
Để ý 1 chút là class int
này kế thừa từ class object
.
Cái này cũng giống như bên .NET
thì object sẽ là abstract class cao nhất, mọi class đều kế thừa từ đấy T_T.
Ngôn ngữ Python hình như hướng đối tượng (OOP) từ lúc mới nghĩ ra. Cái này khác với cả C hồi đầu tiên hự hự.
>>> i.__eq__(5)
False
>>> i==5
False
>>> i.__eq__(1)
True
>>> i==1
True
Thử một vài hàm internal của class int
và thấy là cũng ra kết quả như là mình dùng dấu ==
O_O.
Cái này cũng giống như là overloaded operator trong các kiểu hàm của class O_O.
| __new__(*args, **kwargs) from builtins.type
| Create and return a new object. See help(type) for accurate signature.
|
Tớ thấy có cái này ở trong help(int)
nên thử mò mẫm xem thế nào
>>> help(type)
Help on class type in module builtins:
class type(object)
| type(object_or_name, bases, dict)
| type(object) -> the object's type
| type(name, bases, dict) -> a new type
|
| Methods defined here:
|
| __call__(self, /, *args, **kwargs)
| Call self as a function.
|
| __delattr__(self, name, /)
| Implement delattr(self, name).
|
Hàm type()
dùng để trả về định dạng của 1 biến.
>>> help(object)
Help on class object in module builtins:
class object
| The most base type
Class object là class tổ tiên của tất cả các built-in classes khác O_O.
>>> r=2.5
>>> help(r)
Help on float object:
class float(object)
| float(x) -> floating point number
|
| Convert a string or number to a floating point number, if possible.
|
| Methods defined here:
|
Thử 1 tính năng của hàm help()
.
Hàm help()
có thể tự động tìm kiểu của biến r
và đưa ra tài liệu cho biến ý.
Ở đây là kiểu float (số thực).
>>> help(i==1)
Help on bool object:
class bool(int)
| bool(x) -> bool
|
| Returns True when the argument x is true, False otherwise.
| The builtins True and False are the only two instances of the class bool.
| The class bool is a subclass of the class int, and cannot be subclassed.
|
| Method resolution order:
| bool
| int
| object
| Methods defined here:
|
| __and__(self, value, /)
| Return self&value.
|
| __new__(*args, **kwargs) from builtins.type
| Create and return a new object. See help(type) for accurate signature.
|
| __or__(self, value, /)
| Return self|value.
|
| __rand__(self, value, /)
| Return value&self.
|
| __repr__(self, /)
| Return repr(self).
| ----------------------------------------------------------------------
| Methods inherited from int:
|
| __abs__(self, /)
| abs(self)
|
| __add__(self, value, /)
| Return self+value.
|
| __bool__(self, /)
| self != 0
|
| __ceil__(...)
| Ceiling of an Integral returns itself.
Thử tiếp xem hàm help()
có nhận kiểu khác không :-?
Giá trị trả về của phép kiểm tra i==1
là bool
. Vậy là nhận đúng rồi.
Chú ý ở đây class bool
lại kế thừa từ class int
.
Class int
kế thừa từ class object
.
Vậy là những methods (hàm) gì mà class int
có thì hàm bool
cũng có!!!
Kiểu bool
thì chỉ có 2 giá trị là True và False thôi ^_^.
Kể ra kế thừa từ int
cũng là hợp lý.
>>> s='kid'
>>> help(s)
No Python documentation found for 'kid'.
Use help() to get the interactive help utility.
Use help(str) for help on the str class.
Help on class str in module builtins:
class str(object)
| str(object='') -> str
| str(bytes_or_buffer[, encoding[, errors]]) -> str
|
| Create a new string object from the given object. If encoding or
| errors is specified, then the object must expose a data buffer
| that will be decoded using the given encoding and error handler.
| Otherwise, returns the result of object.__str__() (if defined)
| or repr(object).
| encoding defaults to sys.getdefaultencoding().
| errors defaults to 'strict'.
|
| Methods defined here:
|
| __add__(self, value, /)
| Return self+value.
|
| __contains__(self, key, /)
| Return key in self.
|
Thử xem Help cho String sẽ như thế nào O_O.
>>> sys.getdefaultencoding()
Traceback (most recent call last):
File "<console>", line 1, in <module>
NameError: name 'sys' is not defined
>>> import sys
>>> sys.getdefaultencoding()
'utf-8'
Thử xem default encoding của String là gì đây.
Help on built-in module sys:
NAME
sys
MODULE REFERENCE
https://docs.python.org/3.6/library/sys
The following documentation is automatically generated from the Python
source files. It may be incomplete, incorrect or include features that
are considered implementation detail and may vary between Python
implementations. When in doubt, consult the module reference at the
location listed above.
DESCRIPTION
This module provides access to some objects used or maintained by the
interpreter and to functions that interact strongly with the interpreter.
Dynamic objects:
argv -- command line arguments; argv[0] is the script pathname if known
path -- module search path; path[0] is the script directory, else ''
modules -- dictionary of loaded modules
displayhook -- called to show results in an interactive session
excepthook -- called to handle any uncaught exception other than SystemExit
To customize printing in an interactive session or to install a custom
top-level exception handler, assign other functions to replace these.
stdin -- standard input file object; used by input()
stdout -- standard output file object; used by print()
stderr -- standard error object; used for error messages
By assigning other file objects (or objects that behave like files)
to these, it is possible to redirect all of the interpreter's I/O.
argv = ['manage.py', 'shell']
base_exec_prefix = '/usr'
base_prefix = '/usr'
builtin_module_names = ('_ast', '_bisect', '_blake2', '_codecs', '_col...
byteorder = 'little'
copyright = 'Copyright (c) 2001-2019 Python Software Foundati...ematis...
dont_write_bytecode = False
exec_prefix = '/home/ninehealth/work/moviegeek/venv_3.6.9'
executable = '/home/ninehealth/work/moviegeek/venv_3.6.9/bin/python3'
flags = sys.flags(debug=0, inspect=0, interactive=0, opt...ing=0, quie...
float_info = sys.float_info(max=1.7976931348623157e+308, max_...epsilo...
path_importer_cache = {'/home/ninehealth/work/moviegeek': FileFinder('...
platform = 'linux'
prefix = '/home/ninehealth/work/moviegeek/venv_3.6.9'
ps1 = '>>> '
ps2 = '... '
stderr = <_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF-8'>
stdin = <_io.TextIOWrapper name='<stdin>' mode='r' encoding='UTF-8'>
stdout = <_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>
thread_info = sys.thread_info(name='pthread', lock='semaphore', versio...
version = '3.6.9 (default, Nov 25 2022, 14:10:45) \n[GCC 8.4.0]'
version_info = sys.version_info(major=3, minor=6, micro=9, releaseleve...
warnoptions = []
Tìm hiểu thêm module sys
làm gì.
Ở đây có thể hiểu module chính là 1 file .py
có nhiều class ở bên trong.
Module sys
này tớ cũng thấy các file Python dùng nhiều :-?.
Đặc biệt ở đoạn cuối của phần help (ấn Shift + G
, giống keyboard shortcut của less
) có thể thấy là đường dẫn tuyệt đối tới folder moviegeek
trong môi trường Python ảo T_T.
Mò mẫm để tìm hiểu các built-in functions có sẵn lúc mà vừa mới mở Python ra...
>>> dir()
['__builtins__', 'i', 'r', 's', 'sys']
>>> dir(__builtins__)
['__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']
Thử xem nào.
Có vẻ hàm dir()
cũng hay cơ mà nhìn đau mắt quá @@.
Hàm dir()
ý cũng hiện ra các biến tớ dùng là i
, r
, s
và module sys
được import.
>>> dir(int)
['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floor__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getnewargs__', '__gt__', '__hash__', '__index__', '__init__', '__init_subclass__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes']
>>> dir(float)
['__abs__', '__add__', '__bool__', '__class__', '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getformat__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__int__', '__le__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__pos__', '__pow__', '__radd__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rmod__', '__rmul__', '__round__', '__rpow__', '__rsub__', '__rtruediv__', '__setattr__', '__setformat__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', 'as_integer_ratio', 'conjugate', 'fromhex', 'hex', 'imag', 'is_integer', 'real']
Thử xem class int
có những hàm nào bên trong nào :-?
Có vẻ dir()
list ra cũng đầy đủ đấy. Cho cả class float
nữa.
Python Built-in Functions - W3Schools
https://www.w3schools.com/python/python_ref_functions.asp
1 link tham khảo khác về các hàm có sẵn trong Python.
>>> help(dir)
Help on built-in function dir in module builtins:
dir(...)
dir([object]) -> list of strings
If called without an argument, return the names in the current scope.
Else, return an alphabetized list of names comprising (some of) the attributes
of the given object, and of attributes reachable from it.
If the object supplies a method named __dir__, it will be used; otherwise
the default dir() logic is used and returns:
for a module object: the module's attributes.
for a class object: its attributes, and recursively the attributes
of its bases.
for any other object: its attributes, its class's attributes, and
recursively the attributes of its class's base classes.
Có thể thấy hàm dir()
trả về rất nhiều thứ hay ho @@. Attributes ở đây dịch nôm là thuộc tính.
Nói thật tớ thấy từ attributes hơi sao sao, ở trên nhìn là hiện methods mà nhỉ T_T
Attributes là kiểu như members và data ý hix.
>>> help(builtins)
Help on built-in module builtins:
NAME
builtins - Built-in functions, exceptions, and other objects.
DESCRIPTION
Noteworthy: None is the `nil' object; Ellipsis represents `...' in slices.
CLASSES
object
BaseException
Exception
ArithmeticError
FloatingPointError
OverflowError
ZeroDivisionError
AssertionError
AttributeError
BufferError
EOFError
ImportError
KeyboardInterrupt
SystemExit
bytearray
bytes
classmethod
complex
dict
enumerate
filter
float
frozenset
int
bool
list
map
memoryview
property
range
reversed
set
slice
staticmethod
str
super
tuple
type
zip
FUNCTIONS
__build_class__(...)
__build_class__(func, name, *bases, metaclass=None, **kwds) -> class
Internal helper function used by the class statement.
__import__(...)
__import__(name, globals=None, locals=None, fromlist=(), level=0) -> module
Import a module. Because this function is meant for use by the Python
interpreter and not for general use, it is better to use
importlib.import_module() to programmatically import a module.
delattr(obj, name, /)
Deletes the named attribute from the given object.
delattr(x, 'y') is equivalent to ``del x.y''
dir(...)
dir([object]) -> list of strings
divmod(x, y, /)
Return the tuple (x//y, x%y). Invariant: div*y + mod == x.
DATA
Ellipsis = Ellipsis
False = False
None = None
NotImplemented = NotImplemented
True = True
__debug__ = True
copyright = Copyright (c) 2001-2019 Python Software Foundati...ematisc...
credits = Thanks to CWI, CNRI, BeOpen.com, Zope Corpor...opment. ...
exit = Use exit() or Ctrl-D (i.e. EOF) to exit
help = Type help() for interactive help, or help(object) for help abou...
license = Type license() to see the full license text
quit = Use quit() or Ctrl-D (i.e. EOF) to exit
FILE
(built-in)
Và đây là các built-in classes tớ mong muốn xem đây.
Nhìn ở trên thấy class bool
dịch vào bên trong 4 dấu cách vì được kế thừa từ class int
.
Class object
là cao nhất rùi @@. Class tổ tiên.
Ngoài class hay gặp ra như int
, float
, str
, có thể thấy thêm dict
, list
, set
, frozenset
và rất nhiều class khác mà tớ cũng chưa bao giờ dùng!!!
Có cả các functions sẵn có lúc mà vừa mở Python luôn, có cả dir()
kìa!
>>> import os
>>> dir()
['__builtins__', 'os']
>>> dir(os)
['CLD_CONTINUED', 'CLD_DUMPED', 'CLD_EXITED', 'CLD_TRAPPED', 'DirEntry', 'EX_CANTCREAT', 'EX_CONFIG', 'EX_DATAERR', 'EX_IOERR', 'EX_NOHOST', 'EX_NOINPUT', 'EX_NOPERM', 'EX_NOUSER', 'EX_OK', 'EX_OSERR', 'EX_OSFILE', 'EX_PROTOCOL', 'EX_SOFTWARE', 'EX_TEMPFAIL', 'EX_UNAVAILABLE', 'EX_USAGE', 'F_LOCK', 'F_OK', 'F_TEST', 'F_TLOCK', 'F_ULOCK', 'GRND_NONBLOCK', 'GRND_RANDOM', 'MutableMapping', 'NGROUPS_MAX', 'O_ACCMODE', 'O_APPEND', 'O_ASYNC', 'O_CLOEXEC', 'O_CREAT', 'O_DIRECT', 'O_DIRECTORY', 'O_DSYNC', 'O_EXCL', 'O_LARGEFILE', 'O_NDELAY', 'O_NOATIME', 'O_NOCTTY', 'O_NOFOLLOW', 'O_NONBLOCK', 'O_PATH', 'O_RDONLY', 'O_RDWR', 'O_RSYNC', 'O_SYNC', 'O_TMPFILE', 'O_TRUNC', 'O_WRONLY', 'POSIX_FADV_DONTNEED', 'POSIX_FADV_NOREUSE', 'POSIX_FADV_NORMAL', 'POSIX_FADV_RANDOM', 'POSIX_FADV_SEQUENTIAL', 'POSIX_FADV_WILLNEED', 'PRIO_PGRP', 'PRIO_PROCESS', 'PRIO_USER', 'P_ALL', 'P_NOWAIT', 'P_NOWAITO', 'P_PGID', 'P_PID', 'P_WAIT', 'PathLike', 'RTLD_DEEPBIND', 'RTLD_GLOBAL', 'RTLD_LAZY', 'RTLD_LOCAL', 'RTLD_NODELETE', 'RTLD_NOLOAD', 'RTLD_NOW', 'R_OK', 'SCHED_BATCH', 'SCHED_FIFO', 'SCHED_IDLE', 'SCHED_OTHER', 'SCHED_RESET_ON_FORK', 'SCHED_RR', 'SEEK_CUR', 'SEEK_DATA', 'SEEK_END', 'SEEK_HOLE', 'SEEK_SET', 'ST_APPEND', 'ST_MANDLOCK', 'ST_NOATIME', 'ST_NODEV', 'ST_NODIRATIME', 'ST_NOEXEC', 'ST_NOSUID', 'ST_RDONLY', 'ST_RELATIME', 'ST_SYNCHRONOUS', 'ST_WRITE', 'TMP_MAX', 'WCONTINUED', 'WCOREDUMP', 'WEXITED', 'WEXITSTATUS', 'WIFCONTINUED', 'WIFEXITED', 'WIFSIGNALED', 'WIFSTOPPED', 'WNOHANG', 'WNOWAIT', 'WSTOPPED', 'WSTOPSIG', 'WTERMSIG', 'WUNTRACED', 'W_OK', 'XATTR_CREATE', 'XATTR_REPLACE', 'XATTR_SIZE_MAX', 'X_OK', '_Environ', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_execvpe', '_exists', '_exit', '_fspath', '_fwalk', '_get_exports_list', '_putenv', '_spawnvef', '_unsetenv', '_wrap_close', 'abc', 'abort', 'access', 'altsep', 'chdir', 'chmod', 'chown', 'ch
Thử tiếp thêm module OS có sẵn của Python nào.
Nhiều hàm ghê...
>>> help(os)
NAME
os - OS routines for NT or Posix depending on what system we're on.
MODULE REFERENCE
https://docs.python.org/3.6/library/os
DESCRIPTION
This exports:
- all functions from posix or nt, e.g. unlink, stat, etc.
- os.path is either posixpath or ntpath
- os.name is either 'posix' or 'nt'
- os.curdir is a string representing the current directory (always '.')
- os.pardir is a string representing the parent directory (always '..')
FILE
/usr/lib/python3.6/os.py
Có thể thấy đường dẫn tới file chứ các hàm và class của module os
.
-rwxr-xr-x 1 root root 93303 Nov 25 21:10 tarfile.py*
-rw-r--r-- 1 root root 23136 Nov 25 21:10 telnetlib.py
-rw-r--r-- 1 root root 31867 Nov 25 21:10 tempfile.py
-rw-r--r-- 1 root root 19558 Nov 25 21:10 textwrap.py
-rw-r--r-- 1 root root 1003 Nov 25 21:10 this.py
-rw-r--r-- 1 root root 49029 Nov 25 21:10 threading.py
-rwxr-xr-x 1 root root 13332 Nov 25 21:10 timeit.py*
-rw-r--r-- 1 root root 3075 Nov 25 21:10 token.py
-rw-r--r-- 1 root root 29496 Nov 25 21:10 tokenize.py
-rwxr-xr-x 1 root root 28723 Nov 25 21:10 trace.py*
-rw-r--r-- 1 root root 23458 Nov 25 21:10 traceback.py
-rw-r--r-- 1 root root 16658 Nov 25 21:10 tracemalloc.py
-rw-r--r-- 1 root root 879 Nov 25 21:10 tty.py
-rw-r--r-- 1 root root 143620 Nov 25 21:10 turtle.py
-rw-r--r-- 1 root root 8870 Nov 25 21:10 types.py
-rw-r--r-- 1 root root 80274 Nov 25 21:10 typing.py
-rwxr-xr-x 1 root root 6753 Nov 25 21:10 uu.py*
-rw-r--r-- 1 root root 23971 Nov 25 21:10 uuid.py
-rw-r--r-- 1 root root 18488 Nov 25 21:10 warnings.py
-rw-r--r-- 1 root root 17709 Nov 25 21:10 wave.py
-rw-r--r-- 1 root root 20466 Nov 25 21:10 weakref.py
-rwxr-xr-x 1 root root 21757 Nov 25 21:10 webbrowser.py*
-rw-r--r-- 1 root root 5913 Nov 25 21:10 xdrlib.py
-rw-r--r-- 1 root root 7157 Nov 25 21:10 zipapp.py
-rw-r--r-- 1 root root 76282 Nov 25 21:10 zipfile.py
ninehealth@LinuxVM15:~$ ll /usr/lib/python3.6/ | grep py
Thử mò lần 1.
ninehealth@LinuxVM15:~$ ll /usr/lib/python3.6/ | grep os
-rw-r--r-- 1 root root 19119 Nov 25 21:10 _osx_support.py
-rw-r--r-- 1 root root 37526 Nov 25 21:10 os.py
-rw-r--r-- 1 root root 15772 Nov 25 21:10 posixpath.py
ninehealth@LinuxVM15:~$ ll /usr/lib/python3.6/ | grep sys
-rw-r--r-- 1 root root 22325 Nov 25 21:10 _sysconfigdata_m_linux_x86_64-linux-gnu.py
-rw-r--r-- 1 root root 4064 Nov 25 21:10 colorsys.py
-rw-r--r-- 1 root root 25057 Nov 25 21:10 sysconfig.py
Thử mò lần 2.
>>> import sys
>>> help(sys)
thread_info = sys.thread_info(name='pthread', lock='semaphore', versio...
version = '3.6.9 (default, Nov 25 2022, 14:10:45) \n[GCC 8.4.0]'
version_info = sys.version_info(major=3, minor=6, micro=9, releaseleve...
warnoptions = []
DATA
__stderr__ = <_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF...
__stdin__ = <_io.TextIOWrapper name='<stdin>' mode='r' encoding='UTF-8...
__stdout__ = <_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF...
FILE
(built-in)
Không hiểu module sys.py
ở đâu nữa...
>>> help(list)
Help on class list in module builtins:
class list(object)
| list() -> new empty list
| list(iterable) -> new list initialized from iterable's items
|
| Methods defined here:
|
| __add__(self, value, /)
| Return self+value.
|
| __contains__(self, key, /)
| Return key in self.
|
Tìm hiểu thêm về class list
.
>>> help(dict)
Help on class dict in module builtins:
class dict(object)
| dict() -> new empty dictionary
| dict(mapping) -> new dictionary initialized from a mapping object's
| (key, value) pairs
| dict(iterable) -> new dictionary initialized as if via:
| d = {}
| for k, v in iterable:
| d[k] = v
| dict(**kwargs) -> new dictionary initialized with the name=value pairs
| in the keyword argument list. For example: dict(one=1, two=2)
|
| Methods defined here:
|
| __contains__(self, key, /)
| True if D has a key k, else False.
Tìm hiểu thêm về class dict
.
>>> help(set)
Help on class set in module builtins:
class set(object)
| set() -> new empty set object
| set(iterable) -> new set object
|
| Build an unordered collection of unique elements.
|
| Methods defined here:
|
| __and__(self, value, /)
| Return self&value.
|
| __contains__(...)
| x.__contains__(y) <==> y in x.
Tìm hiểu thêm về class set
.
Help on frozenset object:
class frozenset(object)
| frozenset() -> empty frozenset object
| frozenset(iterable) -> frozenset object
|
| Build an immutable unordered collection of unique elements.
|
| Methods defined here:
|
| __and__(self, value, /)
| Return self&value.
|
| __contains__(...)
| x.__contains__(y) <==> y in x.
|
Và class frozenset
luôn...
>>> help("django")
Help on package django:
NAME
django
PACKAGE CONTENTS
__main__
apps (package)
conf (package)
contrib (package)
core (package)
db (package)
dispatch (package)
forms (package)
http (package)
middleware (package)
shortcuts
template (package)
templatetags (package)
test (package)
urls (package)
utils (package)
views (package)
FUNCTIONS
setup(set_prefix=True)
FUNCTIONS
setup(set_prefix=True)
Configure the settings (this happens as a side effect of accessing the
first setting), configure logging and populate the app registry.
Set the thread-local urlresolvers script prefix if `set_prefix` is True.
DATA
VERSION = (2, 2, 27, 'final', 0)
VERSION
2.2.27
FILE
/home/ninehealth/work/moviegeek/venv_3.6.9/lib/python3.6/site-packages/django/__init__.py
Chú ý ở đây trong hàm help()
là phải để django trong dấu " "
.
Django ở đây được gọi là 1 package.
Trong package Django có rất nhiều packages khác.
Help on package django.db in django:
NAME
django.db
PACKAGE CONTENTS
backends (package)
migrations (package)
models (package)
transaction
utils
Thử xem package Database của Django. Rất nhiều O_O.
Help on package django.db.models in django.db:
NAME
django.db.models
PACKAGE CONTENTS
aggregates
base
constants
constraints
deletion
expressions
fields (package)
functions (package)
indexes
lookups
manager
options
query
query_utils
signals
sql (package)
utils
Thử xem package Model trong Django Database package.
>>> help('django.db.models.query')
Help on module django.db.models.query in django.db.models:
NAME
django.db.models.query - The main QuerySet implementation. This provides the public API for the ORM.
CLASSES
builtins.object
BaseIterable
FlatValuesListIterable
ModelIterable
ValuesIterable
ValuesListIterable
NamedValuesListIterable
EmptyQuerySet
Prefetch
QuerySet
RawQuerySet
RelatedPopulator
builtins.type(builtins.object)
InstanceCheckMeta
DATA
CURSOR = 'cursor'
DJANGO_VERSION_PICKLE_KEY = '_django_version'
GET_ITERATOR_CHUNK_SIZE = 100
LOOKUP_SEP = '__'
REPR_OUTPUT_SIZE = 20
connections = <django.db.utils.ConnectionHandler object>
router = <django.db.utils.ConnectionRouter object>
settings = <LazySettings "prs_project.settings">
FILE
/home/ninehealth/work/moviegeek/venv_3.6.9/lib/python3.6/site-packages/django/db/models/query.py
Chà module query
có vẻ hấp dẫn đây. Cái này chắc sẽ dùng nhiều. Xem thử nào.
django.db.models.query.QuerySet = class QuerySet(builtins.object)
| Represent a lazy database lookup for a set of objects.
|
| Methods defined here:
|
| __and__(self, other)
|
| __bool__(self)
|
| __deepcopy__(self, memo)
| Don't populate the QuerySet's cache.
|
|
| all(self)
| Return a new QuerySet that is a copy of the current one. This allows a
| QuerySet to proxy for a model manager in some cases.
|
|
| ----------------------------------------------------------------------
| Class methods defined here:
|
| as_manager() from builtins.type
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| __dict__
| dictionary for instance variables (if defined)
|
| __weakref__
| list of weak references to the object (if defined)
|
| db
| Return the database used if this query is executed now.
|
| ordered
| Return True if the QuerySet is ordered -- i.e. has an order_by()
| clause or a default ordering on the model (or is empty).
Tiếp tục xem class QuerySet
trong class Query
vì cái này có lẽ sẽ dùng nhiều đây O_O.
Vậy tóm tắt về các khái niệm trong Python là
Cách quản lý class, quản lý module và quản lý cao hơn nữa là packages rất khoa học luôn @@.
Khi mình gọi lệnh import
thì có thể import bất cứ gì từ package tới module tới class luôn!!!
Class không chỉ có trong module mà có trong package cũng được!!!!
>>> from django.db import models
>>> help(models.Model)
Help on class Model in module django.db.models.base:
class Model(builtins.object)
| Methods defined here:
|
| __eq__(self, other)
| Return self==value.
|
| __getstate__(self)
| Hook to allow choosing the attributes to pickle.
|
| __hash__(self)
| Return hash(self).
|
Bắt chước 1 lệnh hay có trong file models.py
Nhìn vào đây có thể hiểu là trong module django.db.models.base
sẽ có class Model
.
Class trong file models.py
sẽ kế thừa từ class Model
này.
>>> import collector
>>> help(collector)
Help on package collector:
NAME
collector
PACKAGE CONTENTS
apps
migrations (package)
models
urls
views
FILE
/home/ninehealth/work/moviegeek/collector/__init__.py
Thử xem package collector
được list ra như thế nào, có các modules gì...
>>> help(collector.models)
Help on module collector.models in collector:
NAME
collector.models
CLASSES
django.db.models.base.Model(builtins.object)
Log
class Log(django.db.models.base.Model)
| Log(id, created, user_id, content_id, event, session_id)
|
| Method resolution order:
| Log
| django.db.models.base.Model
| builtins.object
|
| Methods defined here:
|
| __str__(self)
| Return str(self).
|
| content_id = <django.db.models.query_utils.DeferredAttribute object>
| created = <django.db.models.query_utils.DeferredAttribute object>
| event = <django.db.models.query_utils.DeferredAttribute object>
Thử xem module models
trong collector
app (package) có gì.
Như thấy ở tren là có class Log
được kế thừa từ django.db.models.base.Model
Có vẻ đúng đây.
>>> help('django.db.models.base')
Help on module django.db.models.base in django.db.models:
NAME
django.db.models.base
CLASSES
builtins.object
Deferred
Model
ModelState
ModelStateFieldsCacheDescriptor
builtins.type(builtins.object)
ModelBase
class Deferred(builtins.object)
| Methods defined here:
|
| __repr__(self)
| Return repr(self).
|
| __str__(self)
| Return str(self).
Xem thử module django.db.models.base
có những class gì.
Có class Model
ở trong đấy rùi.
>>> help('django.db.models.base.Model')
Help on class Model in django.db.models.base:
django.db.models.base.Model = class Model(builtins.object)
| Methods defined here:
|
| __eq__(self, other)
| Return self==value.
|
| __getstate__(self)
| Hook to allow choosing the attributes to pickle.
|
| __hash__(self)
| Return hash(self).
|
| __init__(self, *args, **kwargs)
| Initialize self. See help(type(self)) for accurate signature.
|
| clean(self)
| Hook for doing any extra model-wide validation after clean() has been
| called on every field by self.clean_fields. Any ValidationError raised
| by this method will not be associated with a particular field; it will
| have a special-case association with the field defined by NON_FIELD_ERRORS.
|
|
| save(self, force_insert=False, force_update=False, using=None, update_fields=None)
| Save the current instance. Override this in a subclass if you want to
| control the saving process.
|
| The 'force_insert' and 'force_update' parameters can be used to insist
| that the "save" must be an SQL insert or update (or equivalent for
| non-SQL backends), respectively. Normally, they should not be set.
|
Xem thử class Model
có những hàm nào. Có hàm save
cũng hay gặp O_O.
ninehealth@LinuxVM15:~/work/moviegeek$ less -SN venv_3.6.9/lib/python3.6/site-packages/django/db/models/base.py
399 class Model(metaclass=ModelBase):
400
401 def __init__(self, *args, **kwargs):
402 # Alias some things as locals to avoid repeat global lookups
403 cls = self.__class__
404 opts = self._meta
405 _setattr = setattr
406 _DEFERRED = DEFERRED
407
408 pre_init.send(sender=cls, args=args, kwargs=kwargs)
409
410 # Set up the storage for instance state
Thử xem source code của module django.db.models.base
>>> help('django.db')
Help on package django.db in django:
NAME
django.db
PACKAGE CONTENTS
backends (package)
migrations (package)
models (package)
transaction
utils
CLASSES
builtins.Exception(builtins.BaseException)
django.db.utils.Error
django.db.utils.DatabaseError
django.db.utils.DataError
django.db.utils.IntegrityError
django.db.utils.InternalError
django.db.utils.NotSupportedError
django.db.utils.OperationalError
django.db.utils.ProgrammingError
django.db.utils.InterfaceError
class DataError(DatabaseError)
| Common base class for all non-exit exceptions.
|
| Method resolution order:
| DataError
| DatabaseError
class ProgrammingError(DatabaseError)
| Common base class for all non-exit exceptions.
|
| Method resolution order:
| ProgrammingError
| DatabaseError
| Error
| builtins.Exception
| builtins.BaseException
| builtins.object
|
| Data descriptors inherited from Error:
|
| __weakref__
| list of weak references to the object (if defined)
Xem thử phần Help của package django.db
.
Có thể thấy trong Package cũng có Package và Classes!!!
>>> help(Log.objects)
Help on Manager in module django.db.models.manager object:
class Manager(BaseManagerFromQuerySet)
| Method resolution order:
| Manager
| BaseManagerFromQuerySet
| BaseManager
| builtins.object
|
| Data and other attributes defined here:
|
| __slotnames__ = []
|
| ----------------------------------------------------------------------
| Methods inherited from BaseManagerFromQuerySet:
|
| aggregate(self, *args, **kwargs)
| Return a dictionary containing the calculations (aggregation)
| over the current queryset.
|
| If args is present the expression is passed as a kwarg using
| the Aggregate object's default alias.
|
Có thể thấy mọi lần mình muốn dùng gì cho QuerySet là sẽ gõ Log.objects
đầu tiên.
Nhìn ở đây có thể thấy Log.objects chính là Manager
class trong module django.db.models.manager
.
>>> help(Log)
Help on class Log in module collector.models:
class Log(django.db.models.base.Model)
| Log(id, created, user_id, content_id, event, session_id)
|
| Method resolution order:
| Log
| django.db.models.base.Model
| builtins.object
|
| Methods defined here:
|
| __str__(self)
| ----------------------------------------------------------------------
| Data and other attributes defined here:
|
| DoesNotExist = <class 'collector.models.Log.DoesNotExist'>
| The requested object does not exist
|
| MultipleObjectsReturned = <class 'collector.models.Log.MultipleObjects...
| The query returned multiple objects when only one was expected.
|
| objects = <django.db.models.manager.Manager object>
Có thể thấy objects được gán bằng django.db.models.manager.Manager
trong phần help cho class Log
kế thừa từ django.db.models.base.Model
.
>>> help('django.db.models.manager')
Help on module django.db.models.manager in django.db.models:
NAME
django.db.models.manager
CLASSES
builtins.object
BaseManager
ManagerDescriptor
BaseManagerFromQuerySet(BaseManager)
Manager
EmptyManager
class BaseManager(builtins.object)
| Methods defined here:
|
| __eq__(self, other)
| Return self==value.
|
| __hash__(self)
| Return hash(self).
|
class Manager(BaseManagerFromQuerySet)
| Method resolution order:
| Manager
| BaseManagerFromQuerySet
| BaseManager
| builtins.object
|
| Data and other attributes defined here:
|
| __slotnames__ = []
|
| ----------------------------------------------------------------------
| Methods inherited from BaseManagerFromQuerySet:
|
| aggregate(self, *args, **kwargs)
| Return a dictionary containing the calculations (aggregation)
| over the current queryset.
|
| If args is present the expression is passed as a kwarg using
| the Aggregate object's default alias.
|
| annotate(self, *args, **kwargs)
| Return a query set in which the returned objects have been annotated
| with extra data or aggregations.
Xem thử module django.db.models.manager
chứa class Manager
như thế nào.
Nhìn từ phần Help ở trên có thể thấy rằng class EmptyManager
kế thừa từ class Manager
.
Class BaseManagerFromQuerySet
kế thừa từ class BaseManager
tuy nhiên tự nhiên phàn indent của class BaseManagerFromQuerySet
lại bị lùi ra ngoài 4 dấu cách.
Có thể hiểu rằng class Manager
kế thừa từ class BaseManagerFromQuerySet
.
Class BaseManagerFromQuerySet
kế thừa từ class BaseManager
.
Class BaseManager
là class cao nhất trong module django.db.models.manager
.
>>> help('django.db.models.manager.Manager')
Help on class Manager in django.db.models.manager:
django.db.models.manager.Manager = class Manager(BaseManagerFromQuerySet)
| Method resolution order:
| Manager
| BaseManagerFromQuerySet
| BaseManager
| builtins.object
|
| Data and other attributes defined here:
|
| __slotnames__ = []
|
| ----------------------------------------------------------------------
| Methods inherited from BaseManagerFromQuerySet:
|
| aggregate(self, *args, **kwargs)
| Return a dictionary containing the calculations (aggregation)
| over the current queryset.
|
| If args is present the expression is passed as a kwarg using
| the Aggregate object's default alias.
Xem thêm phần Help của class Manager
.
>>> help('django.db.models.manager')
NAME
django.db.models.manager
CLASSES
builtins.object
BaseManager
ManagerDescriptor
BaseManagerFromQuerySet(BaseManager)
Manager
EmptyManager
class BaseManager(builtins.object)
| Methods defined here:
|
| __eq__(self, other)
| Return self==value.
|
| __hash__(self)
class EmptyManager(Manager)
| Method resolution order:
| EmptyManager
| Manager
| BaseManagerFromQuerySet
| BaseManager
| builtins.object
|
| Methods defined here:
|
class Manager(BaseManagerFromQuerySet)
| Method resolution order:
| Manager
| BaseManagerFromQuerySet
| BaseManager
| builtins.object
|
| Data and other attributes defined here:
|
| __slotnames__ = []
class ManagerDescriptor(builtins.object)
| Methods defined here:
|
| __get__(self, instance, cls=None)
|
| __init__(self, manager)
| Initialize self. See help(type(self)) for accurate signature.
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| __dict__
| dictionary for instance variables (if defined)
|
| __weakref__
| list of weak references to the object (if defined)
Tóm tắt phần Help của module django.db.models.manager
.
ninehealth@LinuxVM15:~/work/moviegeek$ less -SN venv_3.6.9/lib/python3.6/site-packages/django/db/models/manager.py
3 from importlib import import_module
4
5 from django.db import router
6 from django.db.models.query import QuerySet
7
8
9 class BaseManager:
10 # To retain order, track each time a Manager instance is created.
11 creation_counter = 0
12
13 # Set to True for the 'objects' managers that are automatically created.
14 auto_created = False
15
100 @classmethod
101 def from_queryset(cls, queryset_class, class_name=None):
102 if class_name is None:
103 class_name = '%sFrom%s' % (cls.__name__, queryset_class.__name__)
104 return type(class_name, (cls,), {
105 '_queryset_class': queryset_class,
106 **cls._get_queryset_methods(queryset_class),
107 })
108
164
165 class Manager(BaseManager.from_queryset(QuerySet)):
166 pass
167
Xem source code của module django.db.models.manager
.
Có thể thấy class Manager
nội dung là pass
. Tớ chưa hiểu lắm loại class này thế nào, chắc sẽ tìm hiểu sao hix.
Mà có 1 cái lạ là class thường kế thừa từ class mà class Manager
này lại kế thừa từ hàm from_queryset()
trong class BaseManager
. Chắc cũng cần tìm hiểu thêm hix.
>>> Log.objects.filter(user_id=3).values()
<QuerySet []>
>>> Log.objects.filter(user_id=4).values()
<QuerySet []>
>>> Log.objects.all.values()
Traceback (most recent call last):
File "<console>", line 1, in <module>
AttributeError: 'function' object has no attribute 'values'
>>> Log.objects.all()
<QuerySet [<Log: user_id: 14271057339, content_id: 10121392, event: details>, <Log: user_id: 14271057339, content_id: 10121392, event: more_details>, <Log: user_id: 14271057339, content_id: 10121392, event: details>, <Log: user_id: 14271057339, content_id: 5618690, event: details>, <Log: user_id: 14271057339, content_id: 5537002, event: details>, <Log: user_id: 14271057339, content_id: 5537002, event: more_details>, <Log: user_id: 14271057339, content_id: 5537002, event: details>, <Log: user_id: 33606199645, content_id: 10152736, event: details>, <Log: user_id: 33606199645, content_id: 10380900, event: details>,
>>> Log.objects.all().values()
<QuerySet [{'id': 1, 'created': datetime.datetime(2022, 12, 14, 11, 37, 29, 805451), 'user_id': '14271057339', 'content_id': '10121392', 'event': 'details', 'session_id': 'ac631f04-7ba3-11ed-afd2-000d3a5a3fa5'}, {'id': 2, 'created': datetime.datetime(2022, 12, 14, 11, 37, 31, 753527), 'user_id': '14271057339', 'content_id': '10121392', 'event': 'more_details', 'session_id': 'ac631f04-7ba3-11ed-afd2-000d3a5a3fa5'}, {'id': 3, 'created': datetime.datetime(2022, 12, 14, 11, 37, 31, 756146), 'user_id': '14271057339', 'content_id': '10121392', 'event': 'details', 'session_id': 'ac631f04-7ba3-11ed-afd2-000d3a5a3fa5'}, {'id': 4, 'created': datetime.datetime(2022, 12, 14, 11, 40, 38, 408286), 'user_id': '14271057339', 'content_id': '5618690', 'event': 'details', 'session_id': 'ac631f04-7ba3-11ed-afd2-000d3a5a3fa5'}, {'id': 5, 'created': datetime.datetime(2022, 12, 14, 11, 44, 13, 825325),
Các lệnh trên tớ thử xem ra như thế nào.
ninehealth@LinuxVM15:~/work/moviegeek$ head -n 40 analytics/views.py
def user(request, user_id):
user_ratings = Rating.objects.filter(user_id=user_id).order_by('-rating')
movies = Movie.objects.filter(movie_id__in=user_ratings.values('movie_id'))
log = Log.objects.filter(user_id=user_id).order_by('-created').values()[:20]
cluster = Cluster.objects.filter(user_id=user_id).first()
ratings = {r.movie_id: r for r in user_ratings}
Đây là file tớ tham khảo :-?.
>>> Log.objects.all().filter(user_id=14271057339)
<QuerySet [<Log: user_id: 14271057339, content_id: 10121392, event: details>, <Log: user_id: 14271057339, content_id: 10121392, event: more_details>, <Log: user_id: 14271057339, content_id: 10121392, event: details>, <Log: user_id: 14271057339, content_id: 5618690, event: details>, <Log: user_id: 14271057339, content_id: 5537002, event: details>, <Log: user_id: 14271057339, content_id: 5537002, event: more_details>, <Log: user_id: 14271057339, content_id: 5537002, event: details>]>
>>> Log.objects.all().filter(user_id=14271057339).values()
<QuerySet [{'id': 1, 'created': datetime.datetime(2022, 12, 14, 11, 37, 29, 805451), 'user_id': '14271057339', 'content_id': '10121392', 'event': 'details', 'session_id': 'ac631f04-7ba3-11ed-afd2-000d3a5a3fa5'}, {'id': 2, 'created': datetime.datetime(2022, 12, 14, 11, 37, 31, 753527), 'user_id': '14271057339', 'content_id': '10121392', 'event': 'more_details', 'session_id': 'ac631f04-7ba3-11ed-afd2-000d3a5a3fa5'}, {'id': 3, 'created': datetime.datetime(2022, 12, 14, 11, 37, 31, 756146), 'user_id': '14271057339', 'content_id': '10121392', 'event': 'details', 'session_id': 'ac631f04-7ba3-11ed-afd2-000d3a5a3fa5'}, {'id': 4, 'created': datetime.datetime(2022, 12, 14, 11, 40, 38, 408286), 'user_id': '14271057339', 'content_id': '5618690', 'event': 'details', 'session_id': 'ac631f04-7ba3-11ed-afd2-000d3a5a3fa5'}, {'id': 5, 'created': datetime.datetime(2022, 12, 14, 11, 44, 13, 825325), 'user_id': '14271057339', 'content_id': '5537002', 'event': 'details', 'session_id': 'ac631f04-7ba3-11ed-afd2-000d3a5a3fa5'}, {'id': 6, 'created': datetime.datetime(2022, 12, 14, 11, 44, 15, 677044), 'user_id': '14271057339', 'content_id': '5537002', 'event': 'more_details', 'session_id': 'ac631f04-7ba3-11ed-afd2-000d3a5a3fa5'}, {'id': 7, 'created': datetime.datetime(2022, 12, 14, 11, 44, 15, 681723), 'user_id': '14271057339', 'content_id': '5537002', 'event': 'details', 'session_id': 'ac631f04-7ba3-11ed-afd2-000d3a5a3fa5'}]>
>>> Log.objects.all().filter(user_id=14271057339).values()[0]
{'id': 1, 'created': datetime.datetime(2022, 12, 14, 11, 37, 29, 805451), 'user_id': '14271057339', 'content_id': '10121392', 'event': 'details', 'session_id': 'ac631f04-7ba3-11ed-afd2-000d3a5a3fa5'}
>>> Log.objects.all().filter(user_id=14271057339).values()[:3]
<QuerySet [{'id': 1, 'created': datetime.datetime(2022, 12, 14, 11, 37, 29, 805451), 'user_id': '14271057339', 'content_id': '10121392', 'event': 'details', 'session_id': 'ac631f04-7ba3-11ed-afd2-000d3a5a3fa5'}, {'id': 2, 'created': datetime.datetime(2022, 12, 14, 11, 37, 31, 753527), 'user_id': '14271057339', 'content_id': '10121392', 'event': 'more_details', 'session_id': 'ac631f04-7ba3-11ed-afd2-000d3a5a3fa5'}, {'id': 3, 'created': datetime.datetime(2022, 12, 14, 11, 37, 31, 756146), 'user_id': '14271057339', 'content_id': '10121392', 'event': 'details', 'session_id': 'ac631f04-7ba3-11ed-afd2-000d3a5a3fa5'}]>
>>> Log.objects.all().filter(user_id=14271057339).values()[1]
{'id': 2, 'created': datetime.datetime(2022, 12, 14, 11, 37, 31, 753527), 'user_id': '14271057339', 'content_id': '10121392', 'event': 'more_details', 'session_id': 'ac631f04-7ba3-11ed-afd2-000d3a5a3fa5'}
>>> Log.objects.all().filter(user_id=14271057339).values()[:3][1]
{'id': 2, 'created': datetime.datetime(2022, 12, 14, 11, 37, 31, 753527), 'user_id': '14271057339', 'content_id': '10121392', 'event': 'more_details', 'session_id': 'ac631f04-7ba3-11ed-afd2-000d3a5a3fa5'}
>>> Log.objects.all().filter(user_id=14271057339).values()[2:5][1]
{'id': 4, 'created': datetime.datetime(2022, 12, 14, 11, 40, 38, 408286), 'user_id': '14271057339', 'content_id': '5618690', 'event': 'details', 'session_id': 'ac631f04-7ba3-11ed-afd2-000d3a5a3fa5'}
>>> Log.objects.all().filter(user_id=14271057339).values()[0]['event']
'details'
>>> Log.objects.filter(user_id=14271057339).values()[0]['event']
'details'
Thử 1 loạt các kiểu QuerySet khác nhau.
>>> Log.objects.count()
135
Thử hàm count()
mà không có all()
vẫn ra hết được kết quả @@. Ảo ghê.
>>> Log.objects.all()[134]
<Log: user_id: 88147736834, content_id: 12929990, event: details>
>>> Log.objects.all()[134].values
Traceback (most recent call last):
File "<console>", line 1, in <module>
AttributeError: 'Log' object has no attribute 'values'
>>> Log.objects.all()[133]
<Log: user_id: 88147736834, content_id: 12929990, event: details>
>>> Log.objects.all()[0]
<Log: user_id: 14271057339, content_id: 10121392, event: details>
Thử lấy phần tử đầu và cuối ra.
>>> Log.objects.all().order_by('-id')
<QuerySet [<Log: user_id: 88147736834, content_id: 12929990, event: details>, <Log: user_id: 88147736834, content_id: 12929990, event: details>, <Log: user_id: 88147736834, content_id: 3228774, event: details>, <Log: user_id: 88147736834, content_id: 0, event: genre:Comedy>, <Log: user_id: 88147736834, content_id: 7230750, event: details>, <Log: user_id: 88147736834, content_id: 0, event: genre:Documentary>, <Log: user_id: 85329678214, content_id: 499097, event: more_details>, <Log: user_id: 85329678214, content_id: 499097, event:
>>> Log.objects.all().order_by('-id').values()
<QuerySet [{'id': 135, 'created': datetime.datetime(2023, 1, 2, 9, 30, 23, 624947), 'user_id': '88147736834', 'content_id': '12929990', 'event': 'details', 'session_id': '0082605a-8a80-11ed-9171-000d3a5a3fa5'}, {'id': 134, 'created': datetime.datetime(2023, 1, 2, 9, 30, 23, 626585), 'user_id': '88147736834', 'content_id': '12929990', 'event': 'details', 'session_id': '0082605a-8a80-11ed-9171-000d3a5a3fa5'}, {'id': 133, 'created': datetime.datetime(2023, 1, 2, 9, 30, 16, 154813), 'user_id': '88147736834', 'content_id': '3228774', 'event': 'details', 'session_id': '0082605a-8a80-11ed-9171-000d3a5a3fa5'}, {'id': 132, 'created': datetime.datetime(2023, 1, 2, 9, 30, 12, 930199), 'user_id': '88147736834', 'content_id': '0', 'event': 'genre:Comedy', 'session_id': '0082605a-8a80-11ed-9171-000d3a5a3fa5'}, {'id': 131, 'created': datetime.datetime(2023, 1, 2, 9, 30, 10, 801889), 'user_id': '88147736834', 'content_id': '7230750', 'event': 'details', 'session_id':
Thử hàm order_by()
sắp xếp lại các phần tử hiển thị.
>>> Log.objects.all().order_by('-id').values('id')
<QuerySet [{'id': 135}, {'id': 134}, {'id': 133}, {'id': 132}, {'id': 131}, {'id': 130}, {'id': 129}, {'id': 128}, {'id': 127}, {'id': 126}, {'id': 125}, {'id': 124}, {'id': 123}, {'id': 122}, {'id': 121}, {'id': 120}, {'id': 119}, {'id': 118}, {'id': 117}, {'id': 116}, '...(remaining elements truncated)...']>
Sắp xếp các phần tử theo thứ tự giảm dần và chỉ hiển thị id thôi.
>>> Log.objects.all().order_by('-id').values('id')[4].values()
dict_values([131])
>>> Log.objects.all().order_by('-id').values('id')[:4].values()
<QuerySet [{'id': 135, 'created': datetime.datetime(2023, 1, 2, 9, 30, 23, 624947), 'user_id': '88147736834', 'content_id': '12929990', 'event': 'details', 'session_id': '0082605a-8a80-11ed-9171-000d3a5a3fa5'}, {'id': 134, 'created': datetime.datetime(2023, 1, 2, 9, 30, 23, 626585), 'user_id': '88147736834', 'content_id': '12929990', 'event': 'details', 'session_id': '0082605a-8a80-11ed-9171-000d3a5a3fa5'}, {'id': 133, 'created': datetime.datetime(2023, 1, 2, 9, 30, 16, 154813), 'user_id': '88147736834', 'content_id': '3228774', 'event': 'details', 'session_id': '0082605a-8a80-11ed-9171-000d3a5a3fa5'}, {'id': 132, 'created': datetime.datetime(2023, 1, 2, 9, 30, 12, 930199), 'user_id': '88147736834', 'content_id': '0', 'event': 'genre:Comedy', 'session_id': '0082605a-8a80-11ed-9171-000d3a5a3fa5'}]>
Hiển thị 4 phần tử cuối cùng.
>>> from moviegeeks.models import Movie,Genre
>>> help(moviegeeks)
Traceback (most recent call last):
File "<console>", line 1, in <module>
NameError: name 'moviegeeks' is not defined
>>> help('moviegeeks')
Help on package moviegeeks:
NAME
moviegeeks
PACKAGE CONTENTS
admin
apps
models
tests
urls
views
FILE
/home/ninehealth/work/moviegeek/moviegeeks/__init__.py
Thử import moviegeeks app (package).
>>> help('moviegeeks.models')
Help on module moviegeeks.models in moviegeeks:
NAME
moviegeeks.models
CLASSES
django.db.models.base.Model(builtins.object)
Genre
Movie
class Genre(django.db.models.base.Model)
| Genre(id, name)
|
| Method resolution order:
| Genre
| django.db.models.base.Model
| builtins.object
|
| Methods defined here:
|
| __str__(self)
| Return str(self).
class Movie(django.db.models.base.Model)
| Movie(movie_id, title, year)
|
| Method resolution order:
| Movie
| django.db.models.base.Model
| builtins.object
|
| Methods defined here:
|
| __str__(self)
| Return str(self).
|
Xem thử các class có trong module moviegeeks.model
trong package (app) moviegeeks.
Có 2 class là Genre
và Movie
.
>>> Movie.objects.count()
38018
>>> Genre.objects.count()
28
Hiển thị số lượng movies và genres (thể loại phim).
>>> Genre.objects.values()
<QuerySet [{'id': 1, 'name': 'Documentary'}, {'id': 2, 'name': 'Short'}, {'id': 3, 'name': 'Horror'}, {'id': 4, 'name': 'Comedy'}, {'id': 5, 'name': 'Action'}, {'id': 6, 'name': 'Adventure'}, {'id': 7, 'name': 'Fantasy'}, {'id': 8, 'name': 'Sci-Fi'}, {'id': 9, 'name': 'Crime'}, {'id': 10, 'name': 'Western'}, {'id': 11, 'name': 'Drama'}, {'id': 12, 'name': 'Romance'}, {'id': 13, 'name': 'History'}, {'id': 14, 'name': 'Family'}, {'id': 15, 'name': 'War'}, {'id': 16, 'name': 'Sport'}, {'id': 17, 'name': 'Biography'}, {'id': 18, 'name': 'Mystery'}, {'id': 19, 'name': 'Thriller'}, {'id': 20, 'name': 'Animation'}, '...(remaining elements truncated)...']>
Hiển thị các thể loại.
>>> Movie.objects.values().order_by('-year')
<QuerySet [{'movie_id': '0293429', 'title': 'Mortal Kombat ', 'year': 2021}, {'movie_id': '0499097', 'title': 'Tom Clancy&x27;s Without Remorse ', 'year': 2021}, {'movie_id': '0870154', 'title': 'Jungle Cruise ', 'year': 2021}, {'movie_id': '0993840', 'title': 'Army of the Dead ', 'year': 2021}, {'movie_id': '1160419', 'title': 'Dune: Part One ', 'year': 2021}, {'movie_id': '1321510', 'title': 'In the Heights ', 'year': 2021}, {'movie_id': '01361336', 'title': 'Tom and Jerry ', 'year': 2021}, {'movie_id': '1361336', 'title': 'Tom and Jerry ', 'year': 2021}, {'movie_id': '1461238', 'title': 'Kurt Vonnegut: Unstuck in Time ', 'year': 2021}, {'movie_id': '1697800', 'title': 'Die in a Gunfight ', 'year': 2021}, {'movie_id': '1893273', 'title': 'The Last Letter from Your Lover ', 'year': 2021}, {'movie_id': '1924245', 'title': 'Cry Macho ', 'year': 2021}, {'movie_id': '2076822', 'title': 'Chaos Walking ', 'year': 2021}, {'movie_id': '2231874', 'title': 'You Belong to Me ', 'year': 2021}, {'movie_id': '2304637', 'title': 'Flag Day ', 'year': 2021}, {'movie_id': '2382320', 'title': 'No Time to Die ', 'year': 2021}, {'movie_id': '2397461', 'title': 'Clifford the Big Red Dog ', 'year': 2021}, {'movie_id': '2401814', 'title': 'The Loneliest Whale: The Search for 52 ', 'year': 2021}, {'movie_id': '2452150', 'title': 'Respect ', 'year': 2021}, {'movie_id': '2458948', 'title': 'Shin Evangelion Gekijôban ', 'year': 2021}, '...(remaining elements truncated)...']>
Hiển thị các phim mới nhất theo năm.
>>> Movie.objects.filter(movie_id='0293429').values()
<QuerySet [{'movie_id': '0293429', 'title': 'Mortal Kombat ', 'year': 2021}]>
Hiển thị nội dung phim Mortal Kombat.
Chú ý không còn dùng hàm all()
nữa @@.
>>> Movie.objects.filter(movie_id='0293429')[0]
<Movie: Mortal Kombat >
Lấy phần tử đầu tiên ra.
>>> Movie.objects.filter(movie_id='0293429')[0].genres
<django.db.models.fields.related_descriptors.create_forward_many_to_many_manager.<locals>.ManyRelatedManager object at 0x7fe57cc03240>
Thử xem các thể loại của phim đấy.
>>> Movie.objects.filter(movie_id='0293429')[0].genres.values()
<QuerySet [{'id': 5, 'name': 'Action'}, {'id': 6, 'name': 'Adventure'}, {'id': 7, 'name': 'Fantasy'}, {'id': 8, 'name': 'Sci-Fi'}, {'id': 19, 'name': 'Thriller'}]>
Giờ mới hiển thị đúng.
>>> Movie.objects.filter(movie_id='0293429')[0].genres.values('name')
<QuerySet [{'name': 'Action'}, {'name': 'Adventure'}, {'name': 'Fantasy'}, {'name': 'Sci-Fi'}, {'name': 'Thriller'}]>
Chỉ hiện thị tên.
https://github.com/9health/moviegeek/blob/master/moviegeeks/models.py
class Genre(models.Model):
name = models.CharField(max_length=64)
def __str__(self):
return self.name
class Movie(models.Model):
movie_id = models.CharField(max_length=16, unique=True, primary_key=True)
title = models.CharField(max_length=512)
year = models.IntegerField(null=True)
genres = models.ManyToManyField(Genre, related_name='movies', db_table='movie_genre')
def __str__(self):
return self.title
Chú ý ở đây là 2 tables này cũng khai báo trong 1 app.
Và có 1 bảng tham chiếu theo kiểu ManyToManyField
.
Nếu viết SQL để hiển thị tên của các thể loại kia rất phức tạp.
Có lẽ cần join 2 bảng đấy!!!
Giờ chỉ cần 1 câu lệnh QuerySet là xong!!
Rất là tiện!!!
annotate
và Count
trong QuerySetninehealth@LinuxVM15:~/work/moviegeek$ nl analytics/views.py
63 def content(request, content_id):
64 print(content_id)
65 movie = Movie.objects.filter(movie_id=content_id).first()
66 user_ratings = Rating.objects.filter(movie_id=content_id)
67 ratings = user_ratings.values('rating')
68 logs = Log.objects.filter(content_id=content_id).order_by('-created').values()[:20]
69 association_rules = SeededRecs.objects.filter(source=content_id).values('target', 'type')
70 print(content_id, " rat:", ratings)
71 movie_title = 'No Title'
72 agv_rating = 0
73 genre_names = []
74 if movie is not None:
75 movie_genres = movie.genres.all() if movie is not None else []
76 genre_names = list(movie_genres.values('name'))
77 ratings = list(r['rating'] for r in ratings)
78 agv_rating = sum(ratings)/len(ratings)
79 movie_title = movie.title
Code tớ tham khảo để viết QuerySet.
|
|
| annotate(self, *args, **kwargs)
| Return a query set in which the returned objects have been annotated
| with extra data or aggregations.
Có 1 hàm rất hay trong QuerySet là annotate()
.
146 def clusters(request):
147 clusters_w_membercount = (Cluster.objects.values('cluster_id')
148 .annotate(member_count=Count('user_id'))
149 .order_by('cluster_id'))
Và được dùng ở đây.
>>> Movie.objects.filter(movie_id='0293429')[0].genres.values('name').annotate(genres_count=Count('name'))
Traceback (most recent call last):
File "<console>", line 1, in <module>
NameError: name 'Count' is not defined
>>> from django.db.models import Count
>>> help(Count)
Help on class Count in module django.db.models.aggregates:
class Count(Aggregate)
| An SQL function call.
|
| Method resolution order:
| Count
| Aggregate
| django.db.models.expressions.Func
| django.db.models.expressions.SQLiteNumericMixin
| django.db.models.expressions.Expression
| django.db.models.expressions.BaseExpression
| django.db.models.expressions.Combinable
| builtins.object
|
| Methods defined here:
|
| __init__(self, expression, filter=None, **extra)
| Initialize self. See help(type(self)) for accurate signature.
|
| convert_value(self, value, expression, connection)
| Expressions provide their own converters because users have the option
| of manually specifying the output_field which may be a different type
| from the one the database returns.
Lần đầu dùng hàm Count
mà không được.
Chà do chưa import
đây.
>>> Movie.objects.filter(movie_id='0293429')[0].genres.values().annotate(genres_count=Count('name'))
<QuerySet [{'id': 5, 'name': 'Action', 'genres_count': 1}, {'id': 6, 'name': 'Adventure', 'genres_count': 1
}, {'id': 7, 'name': 'Fantasy', 'genres_count': 1}, {'id': 8, 'name': 'Sci-Fi', 'genres_count': 1}, {'id': 19, 'name': 'Thriller', 'genres_count': 1}]>
Lần đầu viết chưa đúng lắm.
>>> Movie.objects.filter(movie_id='0293429').values().annotate(genres_count=Count('genres'))
<QuerySet [{'movie_id': '0293429', 'title': 'Mortal Kombat ', 'year': 2021, 'genres_count': 5}]>
>>> Movie.objects.filter(movie_id='0293429')[0].genres.values('name')
<QuerySet [{'name': 'Action'}, {'name': 'Adventure'}, {'name': 'Fantasy'}, {'name': 'Sci-Fi'}, {'name': 'Thriller'}]>
Viết lại nào. Đúng là phim Mortal Kombat có 5 thể loại thật!!!
__in
và __contains
trong QuerySethttps://docs.djangoproject.com/en/4.1/ref/models/querysets/
in
In a given iterable; often a list, tuple, or queryset. It’s not a common use case, but strings (being iterables) are accepted.
Examples:
Entry.objects.filter(id__in=[1, 3, 4])
Entry.objects.filter(headline__in='abc')
SQL equivalents:
SELECT ... WHERE id IN (1, 3, 4);
SELECT ... WHERE headline IN ('a', 'b', 'c');
You can also use a queryset to dynamically evaluate the list of values instead of providing a list of literal values:
inner_qs = Blog.objects.filter(name__contains='Cheddar')
entries = Entry.objects.filter(blog__in=inner_qs)
This queryset will be evaluated as subselect statement:
SELECT ... WHERE blog.id IN (SELECT id FROM ... WHERE NAME LIKE '%Cheddar%')
Còn 1 tính năng nữa hồi trước tớ đọc trên trang tài liệu Django là hàm __in
Quên mất thuật ngữ là gì rồi =.=
Có thể hiểu in
ở đây nghĩa là ở trong 1 list.
Thay vì mình dùng 3 câu lệnh select từng id thì có thể select cả 3 id đấy cùng 1 lúc luôn!!!
>>> Movie.objects.filter(movie_id__in='0000008')
<QuerySet []>
>>> Movie.objects.filter(movie_id__in='0000008').values()
<QuerySet []>
>>> Movie.objects.filter(movie_id='0000008').values()
<QuerySet [{'movie_id': '0000008', 'title': 'Edison Kinetoscopic Record of a Sneeze ', 'year': 1894}]>
>>> Movie.objects.filter(movie_id__in=['0000008']).values()
<QuerySet [{'movie_id': '0000008', 'title': 'Edison Kinetoscopic Record of a Sneeze ', 'year': 1894}]>
Thử mãi mới đúng!!!
>>> Movie.objects.filter(movie_id__contains='0000008').values()
<QuerySet [{'movie_id': '0000008', 'title': 'Edison Kinetoscopic Record of a Sneeze ', 'year': 1894}]>
Thử kiểu khác nào!
count()
trong QuerySet>>> Log.objects.filter(event='buy').values()
<QuerySet [{'id': 22, 'created': datetime.datetime(2022, 12, 15, 9, 34, 29, 584766), 'user_id': '33606199645', 'content_id': '10295212', 'event': 'buy', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 23, 'created': datetime.datetime(2022, 12, 15, 9, 34, 32, 93424), 'user_id': '33606199645', 'content_id': '10295212', 'event': 'buy', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 56, 'created': datetime.datetime(2022, 12, 15, 15, 33, 51, 35223), 'user_id': '33606199645', 'content_id': '10329614', 'event': 'buy', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 61, 'created': datetime.datetime(2022, 12, 15, 15, 34, 13, 231585), 'user_id': '33606199645', 'content_id': '4876134', 'event': 'buy', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 68, 'created': datetime.datetime(2022, 12, 15, 15, 34, 31, 642053), 'user_id': '33606199645', 'content_id': '13863968', 'event': 'buy', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 101, 'created': datetime.datetime(2022, 12, 21, 0, 32, 46, 135319), 'user_id': '68159542309', 'content_id': '3480822', 'event': 'buy', 'session_id': '6079aab2-80bd-11ed-916f-000d3a5a3fa5'}, {'id': 117, 'created': datetime.datetime(2022, 12, 21, 10, 46, 57, 702927), 'user_id': '33606199645', 'content_id': '0993840', 'event': 'buy', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 124, 'created': datetime.datetime(2022, 12, 22, 0, 31, 38, 171056), 'user_id': '85913049150', 'content_id': '3110958', 'event': 'buy', 'session_id': 'c48da1d4-818a-11ed-9170-000d3a5a3fa5'}]>
>>> Log.objects.filter(event='buy').count()
8
Thử hàm count()
nào.
>>> Log.objects.values('id')
<QuerySet [{'id': 1}, {'id': 2}, {'id': 3}, {'id': 4}, {'id': 5}, {'id': 6}, {'id': 7}, {'id': 8}, {'id': 9}, {'id': 10}, {'id': 11}, {'id': 12}, {'id': 13}, {'id': 14}, {'id': 15}, {'id': 16}, {'id': 17}, {'id': 18}, {'id': 19}, {'id': 20}, '...(remaining elements truncated)...']>
>>> Log.objects.filter(user_id=33606199645).values()
<QuerySet [{'id': 8, 'created': datetime.datetime(2022, 12, 14, 12, 12, 19, 562973), 'user_id': '33606199645', 'content_id': '10152736', 'event': 'details', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 9, 'created': datetime.datetime(2022, 12, 14, 12, 29, 42, 83685), 'user_id': '33606199645', 'content_id': '10380900', 'event': 'details', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 10, 'created': datetime.datetime(2022, 12, 14, 12, 29, 45, 168987), 'user_id': '33606199645', 'content_id': '10380900', 'event': 'more_details', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 11, 'created': datetime.datetime(2022, 12, 14, 12, 29, 59, 70184), 'user_id': '33606199645', 'content_id': '0', 'event': 'genre:War', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 17, 'created': datetime.datetime(2022, 12, 15, 9, 34, 21, 84396), 'user_id': '33606199645', 'content_id': '10295212', 'event': 'details', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 18, 'created': datetime.datetime(2022, 12, 15, 9, 34, 22, 894147), 'user_id': '33606199645', 'content_id': '10295212', 'event': 'details', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 19, 'created': datetime.datetime(2022, 12, 15, 9, 34, 23, 45283), 'user_id': '33606199645', 'content_id': '10295212', 'event': 'details', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 20, 'created': datetime.datetime(2022, 12, 15, 9, 34, 25, 745549), 'user_id': '33606199645', 'content_id': '10295212', 'event': 'details', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 21, 'created': datetime.datetime(2022, 12, 15, 9, 34, 25, 747984), 'user_id': '33606199645', 'content_id': '10295212', 'event': 'more_details', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 22, 'created': datetime.datetime(2022, 12, 15, 9, 34, 29, 584766), 'user_id': '33606199645', 'content_id': '10295212', 'event': 'buy', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 23, 'created': datetime.datetime(2022, 12, 15, 9, 34, 32, 93424), 'user_id': '33606199645', 'content_id': '10295212', 'event': 'buy', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 24, 'created': datetime.datetime(2022, 12, 15, 9, 34, 39, 625456), 'user_id': '33606199645', 'content_id': '0', 'event': 'genre:Music', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 35, 'created': datetime.datetime(2022, 12, 15, 9, 57, 3, 980100), 'user_id': '33606199645', 'content_id': '5452210', 'event': 'details', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 36, 'created': datetime.datetime(2022, 12, 15, 9, 57, 4, 153883), 'user_id': '33606199645', 'content_id': '5452210', 'event': 'details', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 37, 'created': datetime.datetime(2022, 12, 15, 9, 57, 6, 197513), 'user_id': '33606199645', 'content_id': '0', 'event': 'genre:Comedy', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 47, 'created': datetime.datetime(2022, 12, 15, 15, 33, 39, 103528), 'user_id': '33606199645', 'content_id': '10329614', 'event': 'details', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 48, 'created': datetime.datetime(2022, 12, 15, 15, 33, 41, 352348), 'user_id': '33606199645', 'content_id': '10329614', 'event': 'save_for_later', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 49, 'created': datetime.datetime(2022, 12, 15, 15, 33, 41, 361762), 'user_id': '33606199645', 'content_id': '10329614', 'event': 'details', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 50, 'created': datetime.datetime(2022, 12, 15, 15, 33, 43, 537681), 'user_id': '33606199645', 'content_id': '10329614', 'event': 'save_for_later', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 51, 'created': datetime.datetime(2022, 12, 15, 15, 33, 43, 578694), 'user_id': '33606199645', 'content_id': '10329614', 'event': 'details', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, '...(remaining elements truncated)...']>
>>> Log.objects.filter(user_id=33606199645).values().count()
57
Thử count xem user trên có bao nhiêu rows trong database.
distinct()
trong QuerySet>>> Log.objects.filter(user_id=33606199645).values('session_id')
<QuerySet [{'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, '...(remaining elements truncated)...']>
>>> Log.objects.filter(user_id=33606199645).values('session_id').distinct()
<QuerySet [{'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}]>
Thử xem tổng cộng có bao nhiêu session từ khi bật MovieGeeks web app.
https://docs.djangoproject.com/en/4.1/ref/models/querysets/
1 link tham khảo nữa về QuerySet
>>> from datetime import date
>>> Log.objects.filter(created__contains=date(2022,12,15)).values()
<QuerySet [{'id': 12, 'created': datetime.datetime(2022, 12, 15, 9, 30, 35, 189061), 'user_id': '69551453075', 'content_id': '10290352', 'event': 'details', 'session_id': '039060a4-7c5b-11ed-96c7-000d3a5a3fa5'}, {'id': 13, 'created': datetime.datetime(2022, 12, 15, 9, 30, 39, 543351), 'user_id': '69551453075', 'content_id': '0', 'event': 'genre:Short', 'session_id': '039060a4-7c5b-11ed-96c7-000d3a5a3fa5'}, {'id': 14, 'created': datetime.datetime(2022, 12, 15, 9, 30, 44, 801273), 'user_id': '69551453075', 'content_id': '0', 'event': 'genre:Short', 'session_id': '039060a4-7c5b-11ed-96c7-000d3a5a3fa5'}, {'id': 15, 'created': datetime.datetime(2022, 12, 15, 9, 30, 47, 330768), 'user_id': '69551453075', 'content_id': '0', 'event': 'genre:Comedy', 'session_id': '039060a4-7c5b-11ed-96c7-000d3a5a3fa5'}, {'id': 16, 'created': datetime.datetime(2022, 12, 15, 9, 30, 50, 816048), 'user_id': '69551453075', 'content_id': '5164438', 'event': 'details', 'session_id': '039060a4-7c5b-11ed-96c7-000d3a5a3fa5'}, {'id': 17, 'created': datetime.datetime(2022, 12, 15, 9, 34, 21, 84396), 'user_id': '33606199645', 'content_id': '10295212', 'event': 'details', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 18, 'created': datetime.datetime(2022, 12, 15, 9, 34, 22, 894147), 'user_id': '33606199645', 'content_id': '10295212', 'event': 'details', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 19, 'created': datetime.datetime(2022, 12, 15, 9, 34, 23, 45283), 'user_id': '33606199645', 'content_id': '10295212', 'event': 'details', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 20, 'created': datetime.datetime(2022, 12, 15, 9, 34, 25, 745549), 'user_id': '33606199645', 'content_id': '10295212', 'event': 'details', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 21, 'created': datetime.datetime(2022, 12, 15, 9, 34, 25, 747984), 'user_id': '33606199645', 'content_id': '10295212', 'event': 'more_details', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 22, 'created': datetime.datetime(2022, 12, 15, 9, 34, 29, 584766), 'user_id': '33606199645', 'content_id': '10295212', 'event': 'buy', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 23, 'created': datetime.datetime(2022, 12, 15, 9, 34, 32, 93424), 'user_id': '33606199645', 'content_id': '10295212', 'event': 'buy', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 24, 'created': datetime.datetime(2022, 12, 15, 9, 34, 39, 625456), 'user_id': '33606199645', 'content_id': '0', 'event': 'genre:Music', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 25, 'created': datetime.datetime(2022, 12, 15, 9, 36, 10, 441607), 'user_id': '69551453075', 'content_id': '5164438', 'event': 'details', 'session_id': '039060a4-7c5b-11ed-96c7-000d3a5a3fa5'}, {'id': 26, 'created': datetime.datetime(2022, 12, 15, 9, 36, 13, 270063), 'user_id': '69551453075', 'content_id': '5109280', 'event': 'details', 'session_id': '039060a4-7c5b-11ed-96c7-000d3a5a3fa5'}, {'id': 27, 'created': datetime.datetime(2022, 12, 15, 9, 36, 14, 716748), 'user_id': '69551453075', 'content_id': '2953050', 'event': 'details', 'session_id': '039060a4-7c5b-11ed-96c7-000d3a5a3fa5'}, {'id': 28, 'created': datetime.datetime(2022, 12, 15, 9, 36, 16, 245302), 'user_id': '69551453075', 'content_id': '1697800', 'event': 'details', 'session_id': '039060a4-7c5b-11ed-96c7-000d3a5a3fa5'}, {'id': 29, 'created': datetime.datetime(2022, 12, 15, 9, 36, 17, 565272), 'user_id': '69551453075', 'content_id': '4733624', 'event': 'details', 'session_id': '039060a4-7c5b-11ed-96c7-000d3a5a3fa5'}, {'id': 30, 'created': datetime.datetime(2022, 12, 15, 9, 36, 20, 101001), 'user_id': '69551453075', 'content_id': '3797512', 'event': 'details', 'session_id': '039060a4-7c5b-11ed-96c7-000d3a5a3fa5'}, {'id': 31, 'created': datetime.datetime(2022, 12, 15, 9, 36, 20, 628633), 'user_id': '69551453075', 'content_id': '4513678', 'event': 'details', 'session_id': '039060a4-7c5b-11ed-96c7-000d3a5a3fa5'}, '...(remaining elements truncated)...']>
>>> Log.objects.filter(created__contains=date(2022,12,15)).values().count()
58
Thử count
xem trong ngày 2022/Dec/15 có bao nhiêu event xảy ra.
>>> Log.objects.filter(created__contains=date(2022,12,14)).values()
<QuerySet [{'id': 1, 'created': datetime.datetime(2022, 12, 14, 11, 37, 29, 805451), 'user_id': '14271057339', 'content_id': '10121392', 'event': 'details', 'session_id': 'ac631f04-7ba3-11ed-afd2-000d3a5a3fa5'}, {'id': 2, 'created': datetime.datetime(2022, 12, 14, 11, 37, 31, 753527), 'user_id': '14271057339', 'content_id': '10121392', 'event': 'more_details', 'session_id': 'ac631f04-7ba3-11ed-afd2-000d3a5a3fa5'}, {'id': 3, 'created': datetime.datetime(2022, 12, 14, 11, 37, 31, 756146), 'user_id': '14271057339', 'content_id': '10121392', 'event': 'details', 'session_id': 'ac631f04-7ba3-11ed-afd2-000d3a5a3fa5'}, {'id': 4, 'created': datetime.datetime(2022, 12, 14, 11, 40, 38, 408286), 'user_id': '14271057339', 'content_id': '5618690', 'event': 'details', 'session_id': 'ac631f04-7ba3-11ed-afd2-000d3a5a3fa5'}, {'id': 5, 'created': datetime.datetime(2022, 12, 14, 11, 44, 13, 825325), 'user_id': '14271057339', 'content_id': '5537002', 'event': 'details', 'session_id': 'ac631f04-7ba3-11ed-afd2-000d3a5a3fa5'}, {'id': 6, 'created': datetime.datetime(2022, 12, 14, 11, 44, 15, 677044), 'user_id': '14271057339', 'content_id': '5537002', 'event': 'more_details', 'session_id': 'ac631f04-7ba3-11ed-afd2-000d3a5a3fa5'}, {'id': 7, 'created': datetime.datetime(2022, 12, 14, 11, 44, 15, 681723), 'user_id': '14271057339', 'content_id': '5537002', 'event': 'details', 'session_id': 'ac631f04-7ba3-11ed-afd2-000d3a5a3fa5'}, {'id': 8, 'created': datetime.datetime(2022, 12, 14, 12, 12, 19, 562973), 'user_id': '33606199645', 'content_id': '10152736', 'event': 'details', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 9, 'created': datetime.datetime(2022, 12, 14, 12, 29, 42, 83685), 'user_id': '33606199645', 'content_id': '10380900', 'event': 'details', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 10, 'created': datetime.datetime(2022, 12, 14, 12, 29, 45, 168987), 'user_id': '33606199645', 'content_id': '10380900', 'event': 'more_details', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 11, 'created': datetime.datetime(2022, 12, 14, 12, 29, 59, 70184), 'user_id': '33606199645', 'content_id': '0', 'event': 'genre:War', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}]>
>>> Log.objects.filter(created__contains=date(2022,12,14)).values().count()
11
Thử count xem trong ngày 2022/Dec/14 có bao nhiêu event xảy ra.
__gt
trong QuerySet>>> Log.objects.filter(pk__gt=100).values()
<QuerySet [{'id': 101, 'created': datetime.datetime(2022, 12, 21, 0, 32, 46, 135319), 'user_id': '68159542309', 'content_id': '3480822', 'event': 'buy', 'session_id': '6079aab2-80bd-11ed-916f-000d3a5a3fa5'}, {'id': 102, 'created': datetime.datetime(2022, 12, 21, 9, 13, 29, 820787), 'user_id': '33606199645', 'content_id': '10121392', 'event': 'details', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 103, 'created': datetime.datetime(2022, 12, 21, 9, 13, 44, 786031), 'user_id': '33606199645', 'content_id': '10155932', 'event': 'details', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 104, 'created': datetime.datetime(2022, 12, 21, 9, 14, 3, 955965), 'user_id': '33606199645', 'content_id': '10155932', 'event': 'more_details', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 105, 'created': datetime.datetime(2022, 12, 21, 9, 14, 3, 969759), 'user_id': '33606199645', 'content_id': '10155932', 'event': 'details', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 106, 'created': datetime.datetime(2022, 12, 21, 9, 21, 57, 882967), 'user_id': '33606199645', 'content_id': '10155932', 'event': 'details', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 107, 'created': datetime.datetime(2022, 12, 21, 10, 38, 15, 585011), 'user_id': '36314581990', 'content_id': '10243676', 'event': 'details', 'session_id': '89280a72-811b-11ed-916f-000d3a5a3fa5'}, {'id': 108, 'created': datetime.datetime(2022, 12, 21, 10, 46, 16, 994504), 'user_id': '33606199645', 'content_id': '993840', 'event': 'details', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 109, 'created': datetime.datetime(2022, 12, 21, 10, 46, 17, 153694), 'user_id': '33606199645', 'content_id': '993840', 'event': 'details', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 110, 'created': datetime.datetime(2022, 12, 21, 10, 46, 17, 958542), 'user_id': '33606199645', 'content_id': '993840', 'event': 'details', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 111, 'created': datetime.datetime(2022, 12, 21, 10, 46, 20, 492223), 'user_id': '33606199645', 'content_id': '993840', 'event': 'save_for_later', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 112, 'created': datetime.datetime(2022, 12, 21, 10, 46, 20, 502071), 'user_id': '33606199645', 'content_id': '993840', 'event': 'details', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 113, 'created': datetime.datetime(2022, 12, 21, 10, 46, 21, 775887), 'user_id': '33606199645', 'content_id': '993840', 'event': 'save_for_later', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 114, 'created': datetime.datetime(2022, 12, 21, 10, 46, 21, 786541), 'user_id': '33606199645', 'content_id': '993840', 'event': 'details', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 115, 'created': datetime.datetime(2022, 12, 21, 10, 46, 23, 247371), 'user_id': '33606199645', 'content_id': '993840', 'event': 'more_details', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 116, 'created': datetime.datetime(2022, 12, 21, 10, 46, 23, 259731), 'user_id': '33606199645', 'content_id': '993840', 'event': 'details', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 117, 'created': datetime.datetime(2022, 12, 21, 10, 46, 57, 702927), 'user_id': '33606199645', 'content_id': '0993840', 'event': 'buy', 'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'id': 118, 'created': datetime.datetime(2022, 12, 22, 0, 6, 15, 51906), 'user_id': '85913049150', 'content_id': '0', 'event': 'genre:Game-Show', 'session_id': 'c48da1d4-818a-11ed-9170-000d3a5a3fa5'}, {'id': 119, 'created': datetime.datetime(2022, 12, 22, 0, 6, 22, 232249), 'user_id': '85913049150', 'content_id': '0', 'event': 'genre:War', 'session_id': 'c48da1d4-818a-11ed-9170-000d3a5a3fa5'}, {'id': 120, 'created': datetime.datetime(2022, 12, 22, 0, 6, 33, 199537), 'user_id': '85913049150', 'content_id': '0', 'event': 'genre:Fantasy', 'session_id': 'c48da1d4-818a-11ed-9170-000d3a5a3fa5'}, '...(remaining elements truncated)...']>
>>> Log.objects.filter(pk__gt=100).values().count()
35
Hiển thị những id có số lớn hơn 100 trong dữ liệu.
>>> help('prs_project')
Help on package prs_project:
NAME
prs_project
PACKAGE CONTENTS
settings
urls
wsgi
FILE
/home/ninehealth/work/moviegeek/prs_project/__init__.py
>>> help('prs_project.urls')
/home/ninehealth/work/moviegeek/venv_3.6.9/lib/python3.6/site-packages/requests/__init__.py:91: RequestsDependencyWarning: urllib3 (1.26.5) or chardet (3.0.4) doesn't match a supported version!
RequestsDependencyWarning)
Help on module prs_project.urls in prs_project:
NAME
prs_project.urls - prs_project URL Configuration
DATA
urlpatterns = [<URLPattern '^$' [name='index']>, <URLResolver <module ...
FILE
/home/ninehealth/work/moviegeek/prs_project/urls.py
Xem phần Help của PRS.
>>> Log.objects.values('session_id').distinct()
<QuerySet [{'session_id': 'ac631f04-7ba3-11ed-afd2-000d3a5a3fa5'}, {'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5'}, {'session_id': '039060a4-7c5b-11ed-96c7-000d3a5a3fa5'}, {'session_id': '3e9ba490-7c76-11ed-a073-000d3a5a3fa5'}, {'session_id': '133225e2-7f58-11ed-a073-000d3a5a3fa5'}, {'session_id': '8c8cf902-7f59-11ed-a073-000d3a5a3fa5'}, {'session_id': '6079aab2-80bd-11ed-916f-000d3a5a3fa5'}, {'session_id': '89280a72-811b-11ed-916f-000d3a5a3fa5'}, {'session_id': 'c48da1d4-818a-11ed-9170-000d3a5a3fa5'}, {'session_id': '1e717692-8764-11ed-9171-000d3a5a3fa5'}, {'session_id': '0082605a-8a80-11ed-9171-000d3a5a3fa5'}]>
>>> Log.objects.values('session_id').distinct().count()
11
Đếm số lượng Session ID.
https://www.w3schools.com/django/django_queryset.php
1 trang web tham khảo khác về QuerySet.
>>> Log.objects.values('session_id').annotate(session_count=Count('session_id'))
<QuerySet [{'session_id': '0082605a-8a80-11ed-9171-000d3a5a3fa5', 'session_count': 6}, {'session_id': '039060a4-7c5b-11ed-96c7-000d3a5a3fa5', 'session_count': 15}, {'session_id': '133225e2-7f58-11ed-a073-000d3a5a3fa5', 'session_count': 10}, {'session_id': '1e717692-8764-11ed-9171-000d3a5a3fa5', 'session_count': 2}, {'session_id': '3e9ba490-7c76-11ed-a073-000d3a5a3fa5', 'session_count': 9}, {'session_id': '6079aab2-80bd-11ed-916f-000d3a5a3fa5', 'session_count': 10}, {'session_id': '87524f50-7ba8-11ed-afd2-000d3a5a3fa5', 'session_count': 57}, {'session_id': '89280a72-811b-11ed-916f-000d3a5a3fa5', 'session_count': 1}, {'session_id': '8c8cf902-7f59-11ed-a073-000d3a5a3fa5', 'session_count': 8}, {'session_id': 'ac631f04-7ba3-11ed-afd2-000d3a5a3fa5', 'session_count': 7}, {'session_id': 'c48da1d4-818a-11ed-9170-000d3a5a3fa5', 'session_count': 10}]>
Thêm số lượng Session trong từng Session ID!!!
>>> Log.objects.values('user_id').distinct()
<QuerySet [{'user_id': '14271057339'}, {'user_id': '33606199645'}, {'user_id': '69551453075'}, {'user_id': '30159478644'}, {'user_id': '68256497607'}, {'user_id': '73165680939'}, {'user_id': '68159542309'}, {'user_id': '36314581990'}, {'user_id': '85913049150'}, {'user_id': '85329678214'}, {'user_id': '88147736834'}]>
>>> Log.objects.values('user_id').distinct().count()
11
Tính số lượng unique users.
>>> Log.objects.values('event').distinct()
<QuerySet [{'event': 'details'}, {'event': 'more_details'}, {'event': 'genre:War'}, {'event': 'genre:Short'}, {'event': 'genre:Comedy'}, {'event': 'buy'}, {'event': 'genre:Music'}, {'event': 'genre:Action'}, {'event': 'save_for_later'}, {'event': 'genre:Adventure'}, {'event': 'genre:Talk-Show'}, {'event': 'genre:Documentary'}, {'event': 'genre:Biography'}, {'event': 'genre:Film-Noir'}, {'event': 'genre:History'}, {'event': 'genre:Game-Show'}, {'event': 'genre:Fantasy'}]>
>>> Log.objects.values('event').distinct().count()
17
Xem số lượng unique events.
>>> uniq_users = Log.objects.values('user_id').distinct()
>>> for user in uniq_users:
... print(user)
...
{'user_id': '14271057339'}
{'user_id': '33606199645'}
{'user_id': '69551453075'}
{'user_id': '30159478644'}
{'user_id': '68256497607'}
{'user_id': '73165680939'}
{'user_id': '68159542309'}
{'user_id': '36314581990'}
{'user_id': '85913049150'}
{'user_id': '85329678214'}
{'user_id': '88147736834'}
Hiển thị User ID.
>>> Log.objects.filter(user_id=14271057339).values('created')
<QuerySet [{'created': datetime.datetime(2022, 12, 14, 11, 37, 29, 805451)}, {'created': datetime.datetime(2022, 12, 14, 11, 37, 31, 753527)}, {'created': datetime.datetime(2022, 12, 14, 11, 37, 31, 756146)}, {'created': datetime.datetime(2022, 12, 14, 11, 40, 38, 408286)}, {'created': datetime.datetime(2022, 12, 14, 11, 44, 13, 825325)}, {'created': datetime.datetime(2022, 12, 14, 11, 44, 15, 677044)}, {'created': datetime.datetime(2022, 12, 14, 11, 44, 15, 681723)}]>
>>> Log.objects.filter(user_id=14271057339).values('created').first()
{'created': datetime.datetime(2022, 12, 14, 11, 37, 29, 805451)}
>>> Log.objects.filter(user_id=14271057339).values('created').first()
{'created': datetime.datetime(2022, 12, 14, 11, 37, 29, 805451)}
>>> Log.objects.filter(user_id=14271057339).values('created').first()['created']
datetime.datetime(2022, 12, 14, 11, 37, 29, 805451)
>>> type(Log.objects.filter(user_id=14271057339).values('created').first()['created'])
<class 'datetime.datetime'>
>>> print(Log.objects.filter(user_id=14271057339).values('created').first()['created'])
2022-12-14 11:37:29.805451
>>> print(2, Log.objects.filter(user_id=14271057339).values('created').first()['created'])
2 2022-12-14 11:37:29.805451
Làm quen với hàm date
trong module datetime
.
>>> for user in uniq_users:
... user_id = user['user_id']
... first_created_date = Log.objects.filter(user_id=user_id).values('created').first()['created']
... print(user_id, "|", first_created_date)
...
14271057339 | 2022-12-14 11:37:29.805451
33606199645 | 2022-12-14 12:12:19.562973
69551453075 | 2022-12-15 09:30:35.189061
30159478644 | 2022-12-15 12:45:11.904543
68256497607 | 2022-12-19 04:47:23.331939
73165680939 | 2022-12-19 04:57:11.047484
68159542309 | 2022-12-21 00:10:25.121021
36314581990 | 2022-12-21 10:38:15.585011
85913049150 | 2022-12-22 00:06:15.051906
85329678214 | 2022-12-29 11:10:33.041959
88147736834 | 2023-01-02 09:30:06.860626
Hiển thị thời gian đầu tiên user được tạo ra.
>>> Log.objects.filter(user_id=14271057339).annotate(event_count=Count('event')).values('created', 'event_count').first()
{'created': datetime.datetime(2022, 12, 14, 11, 37, 29, 805451), 'event_count': 1}
Hiển thị các event của user này cơ mà viết bị sai...
>>> uniq_users = Log.objects.values('user_id').annotate(event_count=Count('user_id'))
>>> uniq_users
<QuerySet [{'user_id': '14271057339', 'event_count': 7}, {'user_id': '30159478644', 'event_count': 9}, {'user_id': '33606199645', 'event_count': 57}, {'user_id': '36314581990', 'event_count': 1}, {'user_id': '68159542309', 'event_count': 10}, {'user_id': '68256497607', 'event_count': 10}, {'user_id': '69551453075', 'event_count': 15}, {'user_id': '73165680939', 'event_count': 8}, {'user_id': '85329678214', 'event_count': 2}, {'user_id': '85913049150', 'event_count': 10}, {'user_id': '88147736834', 'event_count': 6}]>
>>> uniq_users = Log.objects.values('user_id').annotate(event_count=Count('user_id'))
>>> for user in uniq_users:
... user_id = user['user_id']
... first_created_date = Log.objects.filter(user_id=user_id).values('created').first()['created']
... event_count = user['event_count']
... print(user_id, "|", first_created_date, "|", event_count)
...
14271057339 | 2022-12-14 11:37:29.805451 | 7
30159478644 | 2022-12-15 12:45:11.904543 | 9
33606199645 | 2022-12-14 12:12:19.562973 | 57
36314581990 | 2022-12-21 10:38:15.585011 | 1
68159542309 | 2022-12-21 00:10:25.121021 | 10
68256497607 | 2022-12-19 04:47:23.331939 | 10
69551453075 | 2022-12-15 09:30:35.189061 | 15
73165680939 | 2022-12-19 04:57:11.047484 | 8
85329678214 | 2022-12-29 11:10:33.041959 | 2
85913049150 | 2022-12-22 00:06:15.051906 | 10
88147736834 | 2023-01-02 09:30:06.860626 | 6
Sửa lại cho đúng và hiển thị được số lượng event đi kèm với user.
>>> import moviegeeks
>>> help(moviegeeks)
Help on package moviegeeks:
NAME
moviegeeks
PACKAGE CONTENTS
admin
apps
models
tests
urls
views
FILE
/home/ninehealth/work/moviegeek/moviegeeks/__init__.py
Định thử tiếp 1 ít với app (package) moviegeeks cơ mà có lẽ QuerySet tìm hiểu thế là đủ rồi!!!
Thanks Quang giới thiệu cuốn sách dùng Django rất nhiều này nhé O_O.
Quả thật là QuerySet thật là mạnh đấy!!!
Ngoài ra tớ cũng hiểu hơn về class, kế thừa khi dùng Help function built-in của Python!!!
Rất là hữu ích mặc dù không có visualization gì cả O_O. Tưởng tượng trong đầu hết thôi.
Và tớ thấy mọi thứ rất gọn gàng và clean, kể cả phần Help.
Có thể thấy có được cái đấy ngoài công của bác nghĩ ra còn do cộng đồng nữa!!!
Bảo sao Google dùng Python rất nhiều ._.
Một lần nữa thanks Quang và sorry đã gửi comment muộn.
Mai chắc là tớ quay lại với Chương 5 được rồi!!! Đã study xong QuerySet rồi. Có lẽ cần 1 Wiki document nữa hix.
Hello @quangvv9Life,
Tớ nghĩ task này cũng hòm hòm rùi @_@.
QuerySet hay hơn nhiều SQL cơ mà cần biết lập trình 1 xíu ^_^
Tớ sẽ chuyển task này sang trạng thái Review
nhé!!!
Thanks Quang!!!
Hi Hải,
Không hiểu sao tớ bị miss mất 2 comments 3 ngày trước của Hải cho task này.
Đọc qua về querySet và help thì tớ hiểu đó là 2 công cụ để tìm hiểu về python, django và database Qua việc hiểu rõ về dữ liệu rồi và tìm hiểu thêm về các thuật toán thì mình sẽ hiểu được cách xử lí của các thuật toán đó trên dữ liệu và kết quả dữ liệu đầu ra như thế nào. Và từ việc hiểu về dữ liệu thì cũng là cơ sở để thay ruột bằng dữ liệu "foods" và "exercises" và từ đó tìm được thuật toán phù hợp và sửa lại trên bộ dữ liệu mới
BR
Description
Expected result