ํ์ฑ๋ ๊ด๊ณ์ ์ํด์
๊ด๊ณ๋ฅผ ๋งบ์ ํ
์ด๋ธ์ ์ ๊ทผ์ด ๊ฐ๋ฅํด์ง!
Reporter : Article = 1 : M
>>> r1 = Reporter.objects.get(id=1)
>>> r1
<Reporter: John Smith>
>>>
>>> dir(r1)
['DoesNotExist', 'MultipleObjectsReturned', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_check_column_name_clashes', '_check_constraints', '_check_field_name_clashes', '_check_fields', '_check_id_field', '_check_index_together', '_check_indexes', '_check_local_fields', '_check_long_column_names', '_check_m2m_through_same_relationship', '_check_managers', '_check_model', '_check_model_name_db_lookup_clashes', '_check_ordering', '_check_property_name_related_field_accessor_clashes', '_check_single_primary_key', '_check_swappable', '_check_unique_together', '_do_insert', '_do_update', '_get_FIELD_display', '_get_next_or_previous_by_FIELD', '_get_next_or_previous_in_order', '_get_pk_val', '_get_unique_checks', '_meta', '_perform_date_checks', '_perform_unique_checks', '_save_parents', '_save_table', '_set_pk_val', '_state',
'article_set',
'check', 'clean', 'clean_fields', 'date_error_message',
'delete',
'email', 'first_name',
'from_db', 'full_clean', 'get_deferred_fields',
'id', 'last_name',
'objects', 'pk',
'prepare_database_save', 'refresh_from_db',
'save', 'save_base',
'serializable_value', 'unique_error_message', 'validate_unique']
>>>
>>> r1
<Reporter: John Smith>
>>>
>>> dir(r1.article_set)
['__call__', '__class__', '__class_getitem__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slotnames__', '__str__', '__subclasshook__', '__weakref__', '_apply_rel_filters', '_constructor_args', '_db', '_get_queryset_methods', '_hints', '_insert', '_queryset_class', '_remove_prefetched_objects', '_set_creation_counter', '_update',
'add', 'aggregate', 'all', 'annotate',
'auto_created', 'bulk_create', 'bulk_update',
'check', 'complex_filter', 'contribute_to_class',
'core_filters', 'count',
'create', 'creation_counter', 'dates', 'datetimes',
'db', 'db_manager', 'deconstruct',
'defer', 'difference',
'distinct', 'do_not_call_in_templates',
'earliest', 'exclude',
'exists', 'explain', 'extra', 'field', 'filter',
'first',
'from_queryset',
'get', 'get_or_create', 'get_prefetch_queryset', 'get_queryset',
'in_bulk', 'instance', 'intersection', 'iterator',
'last', 'latest', 'model',
'name', 'none', 'only',
'order_by', 'prefetch_related',
'raw', 'reverse',
'select_for_update', 'select_related',
'set', 'union', 'update', 'update_or_create',
'use_in_migrations', 'using',
'values', 'values_list']
>>>
>>> a1 = Article.objects.get(id=1)
>>> dir(a1)
['DoesNotExist', 'MultipleObjectsReturned', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_check_column_name_clashes', '_check_constraints', '_check_field_name_clashes', '_check_fields', '_check_id_field', '_check_index_together', '_check_indexes', '_check_local_fields', '_check_long_column_names', '_check_m2m_through_same_relationship', '_check_managers', '_check_model', '_check_model_name_db_lookup_clashes', '_check_ordering', '_check_property_name_related_field_accessor_clashes', '_check_single_primary_key', '_check_swappable', '_check_unique_together', '_do_insert', '_do_update', '_get_FIELD_display', '_get_next_or_previous_by_FIELD', '_get_next_or_previous_in_order', '_get_pk_val', '_get_unique_checks', '_meta', '_perform_date_checks', '_perform_unique_checks', '_save_parents', '_save_table', '_set_pk_val', '_state',
'check', 'clean', 'clean_fields', 'date_error_message',
'delete',
'from_db', 'full_clean',
'get_deferred_fields', 'get_next_by_pub_date', 'get_previous_by_pub_date',
'headline',
'id', 'objects', 'pk',
'prepare_database_save',
'pub_date',
'refresh_from_db',
'reporter', 'reporter_id',
'save', 'save_base',
'serializable_value', 'unique_error_message', 'validate_unique']
>>>
>>> r1
<Reporter: John Smith>
>>> r1.article_set.filter(headline__startswith='This')
<QuerySet [<Article: This is a test>]>
>>>
>>> Article.objects.filter(reporter__first_name='John')
<QuerySet [<Article: John's second story>, <Article: This is a test>]>
>>>
>>> Article.objects.filter(reporter__first_name='John', reporter__last_name='Smith')
<QuerySet [<Article: John's second story>, <Article: This is a test>]>
>>>
>>> Article.objects.filter(reporter__pk=1)
<QuerySet [<Article: John's second story>, <Article: This is a test>]>
>>>
>>> Article.objects.filter(reporter=1)
<QuerySet [<Article: John's second story>, <Article: This is a test>]>
>>>
>>> Article.objects.filter(reporter=r1)
<QuerySet [<Article: John's second story>, <Article: This is a test>]>
>>> r1
<Reporter: John Smith>
>>>
>>> Article.objects.filter(reporter__in=[1,2]).distinct()
<QuerySet [<Article: John's second story>, <Article: Paul's story>, <Article: This is a test>]>
>>>
>>> r1,r2
(<Reporter: John Smith>, <Reporter: Paul Jones>)
>>>
>>> Article.objects.filter(reporter__in=[r1,r2]).distinct()
<QuerySet [<Article: John's second story>, <Article: Paul's story>, <Article: This is a test>]>
>>>
>>> Article.objects.filter(reporter__in=Reporter.objects.filter(first_name='John')).distinct()
<QuerySet [<Article: John's second story>, <Article: This is a test>]>
>>>
>>> Reporter.ojbects.filter(article__pk=1)
Traceback (most recent call last):
File "<console>", line 1, in <module>
AttributeError: type object 'Reporter' has no attribute 'ojbects'
>>>
>>>
>>> Reporter.objects.filter(article__pk=1)
<QuerySet [<Reporter: John Smith>]>
>>> Reporter.objects.filter(article=1)
<QuerySet [<Reporter: John Smith>]>
>>> Reporter.objects.filter(article=a1)
<QuerySet [<Reporter: John Smith>]>
>>> Reporter.objects.filter(article__headline__startswith='This')
<QuerySet [<Reporter: John Smith>]>
>>> Reporter.objects.filter(article__headline__startswith='This').distinct()
<QuerySet [<Reporter: John Smith>]>
>>> Reporter.objects.filter(article__headline__startswith='This').count()
1
>>> Reporter.objects.filter(article__headline__startswith='This').distinct().count()
1
>>>
>>> Reporter.objects.filter(article__reporter__first_name__startswith='John')
<QuerySet [<Reporter: John Smith>, <Reporter: John Smith>]>
>>> Reporter.objects.filter(article__reporter__first_name__startswith='John').distinct()
<QuerySet [<Reporter: John Smith>]>
>>> Reporter.objects.filter(article__reporter=r1).distinct()
<QuerySet [<Reporter: John Smith>]>
>>> r1
<Reporter: John Smith>
>>>
>>> Reporter.objects.filter(article__headline__startswith='This')
<QuerySet [<Reporter: John Smith>]>
>>>
>>> Reporter.objects.filter(article__headline__startswith='This').delete()
(3, {'practice.Article': 2, 'practice.Reporter': 1})
>>>
>>> Reporter.objects.filter(article__headline__startswith='This')
<QuerySet []>
>>>
ํผ์ ๋ชจ๋ธ์๋ค๊ฐ ManyToManyField์ธ ์์ฑ์ ๋ฃ์ด๋ ๋๊ณ
์๋๋ฉด, ํ ํ์๋ค๊ฐ ManyToManyField์ธ ์์ฑ์ ๋ฃ์ด์
ํผ์์ ํ ํ ํ
์ด๋ธ ์ฌ์ด์ ๊ด๊ณ๋ฅผ ๋ํ๋ด๋ฉด ๋๋ค!
๊ทธ๋ฌ๋, ์ฅ๊ณ ์ "form"์ ์ด์ฉํ๋ค๋ฉด!
ํผ์๋ฅผ ์ ํํ๊ณ ํ ํ์ ์ ํํ๋ ๊ฒ์ด ๋ ์์ฐ์ค๋ฝ๊ธฐ์!
ํผ์์๋ค๊ฐ ManyToManyField ์์ฑ์ ๋ฃ์ด์ ํ ํ์ ์ฐ๊ฒฐํด์ฃผ๋ ๊ฒ์ด ๋ ์ข์ผ๋น!
์์ฑ๋ ๋ฌผ๋ฆฌํ ์ด๋ธ ์๋์ ๊ฐ๋น
class HappyPerson(models.Model):
friends = models.ManyToManyField("self")
CREATE TABLE "practice_happyperson" (
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT
)
CREATE TABLE "practice_happyperson_friends" (
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
"from_happyperson_id" integer NOT NULL REFERENCES
"practice_happyperson" ("id") DEFERRABLE INITIALLY DEFERRED,
"to_happyperson_id" integer NOT NULL REFERENCES
"practice_happyperson" ("id") DEFERRABLE INITIALLY DEFERRED
)