Python | Django | モデルを用いた様々なテーブルからの値の取得方法
公開日:2021/7/4
Pythonには,DjangoというWebアプリケーションフレームワークがある.フレームワークのため,Djangoを利用するとWebアプリを通常よりも短時間で開発することが可能になる.
前記事にて,「モデルを用いたテーブル間の紐づけにおけるmany-to-manyの使い方」を記した.前記事での設定をそのまま引き継いだ上で,本記事では,「モデルを用いた様々なテーブルからの値の取得方法」を以下にて記す.
なお,以下(1)~(3)は,2021/7/1~3に作成している.以下(1)では"many-to-one relationships"(多対1),(2)では"one-to-one relationships"(1対1),(3)では"many-to-many relationships"(多対多)を利用している.
(1) モデルを用いたテーブル間の紐づけにおけるon_delete optionの使い方
(2) モデルを用いたテーブル間の紐づけにおけるone-to-oneの使い方
(3) モデルを用いたテーブル間の紐づけにおけるmany-to-manyの使い方
上記(1)~(3)を利用し,以下1~4の構成にて本記事を記す.
- 準備
- “many-to-one relationships"(多対1)における値の取得方法
- “one-to-one relationships"(多対1)における値の取得方法
- “many-to-many relationships"(多対1)における値の取得方法
◆実施環境
Python 3.8.8
Django 3.2.3
■モデルを用いた様々なテーブルからの値の取得方法
“model_project"に"extract_val.py"を以下のように作成する.
“model_app/models.py"に記載されている内容は以下になる."models.py"に"many-to-one relationships"(多対1),"one-to-one relationships"(1対1),"many-to-many relationships"(多対多)が記載されている.
from django.db import models
from django.utils import timezone
class
Date(models.Model):
# 抽象基底クラス
create_date = models.DateTimeField(default=timezone.now)
update_date = models.DateTimeField(default=timezone.now)
class
Meta:
abstract =
True
class
Cake(Date):
cake_name = models.CharField(max_length=40)
birthplace = models.CharField(max_length=40)
birthday = models.DateField(default='1900-01-01')
inventor = models.CharField(max_length=40)
sales_amounts = models.IntegerField()
like = models.BooleanField(default=True)
email = models.EmailField(db_index=True)
web_site = models.URLField()
feed_back = models.TextField(null=True,blank=True)
class
Meta:
db_table =
'cake'
index_together =
[['cake_name','inventor']]
ordering =
['birthday']
def
__str__(self):
return
f'{self.cake_name}'
# 以下"many-to-one relationships"の記載
class
Dorayakis(models.Model):
name = models.CharField(max_length=30)
price = models.IntegerField()
birthday = models.DateField(default='1900-01-01')
shop = models.ForeignKey(
'Shops', on_delete=models.RESTRICT
)
city = models.ForeignKey(
'Cities', on_delete=models.CASCADE
)
class
Meta:
db_table =
'dorayakis'
class
Shops(models.Model):
name = models.CharField(max_length=30)
city = models.ForeignKey(
'Cities', on_delete=models.CASCADE
)
class
Meta:
db_table =
'shops'
class
Cities(models.Model):
name = models.CharField(max_length=30)
class
Meta:
db_table =
'cities'
# 以下"one-to-one relationships"の記載
class
Places(models.Model):
name = models.CharField(max_length=50)
address = models.CharField(max_length=80)
class
Meta:
db_table =
'places'
class
Companies(models.Model):
place = models.OneToOneField(
Places,
on_delete=models.CASCADE,
primary_key=True
)
name = models.CharField(max_length=50)
class
Meta:
db_table =
'companies'
# 以下"many-to-many relationships"の記載
class
Musics(models.Model):
name = models.CharField(max_length=50)
def
__str__(self):
return self.name
class
Meta:
db_table =
'musics'
class
Musicians(models.Model):
name = models.CharField(max_length=30)
musics = models.ManyToManyField(Musics)
# ManyToManyFieldの利用
def
__str__(self):
return self.name
class
Meta:
db_table =
'musicians'
“model_app/models.py"において,"ForeignKey"が含まれているクラスの場合,「クラスインスタンス名.フィールド名」を利用し,"ForeignKey"が含まれていないクラスの場合,「クラスインスタンス名.フィールド名_set.all()」を利用する.
なお,"extract_val.py"は以下のように編集する.
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE','model_project.settings')
from django import setup
setup()
from model_app.models import Dorayakis, Shops, Cities
# 1の処理(first:テーブルの1番最初の値)
s1 = Shops.objects.first()
print(s1)
# 2の処理
print(type(s1))
# 3の処理
print(dir(s1))
# 4の処理(last:テーブルの1番最後の値)
s2 = Shops.objects.last()
print(s2)
# 5の処理(all:テーブルのすべての値)
s3 = Shops.objects.all()
print(s3)
# 6の処理
print(s1.city.name)
# 7の処理(s1に接続するdorayakisの値をすべて出力)
print(s1.dorayakis_set.all())
# 8の処理
print(type(s1.dorayakis_set))
# 9の処理
print(dir(s1.dorayakis_set))
■実行結果
# 3の結果より,以下を注目すると関わるテーブルが1なのか多なのかが分かる.
'city’: 1を意味している.
'dorayakis_set’: 多を意味している.
# 1の結果
Shops object (4)
# 2の結果
<class 'model_app.models.Shops'>
# 3の結果
['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_default_pk', '_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_expr_references',
'_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', '_prepare_related_fields_for_save',
'_save_parents', '_save_table', '_set_pk_val', '_state', 'check', 'city',
'city_id', 'clean', 'clean_fields', 'date_error_message', 'delete',
'dorayakis_set', 'from_db', 'full_clean', 'get_deferred_fields', 'id',
'name', 'objects', 'pk', 'prepare_database_save', 'refresh_from_db',
'save', 'save_base', 'serializable_value', 'unique_error_message',
'validate_unique']
# 4の結果
Shops object (6)
# 5の結果
<QuerySet [<Shops: Shops object (4)>, <Shops: Shops object (5)>,
<Shops: Shops object (6)>]>
# 6の結果
北区
# 7の結果
<QuerySet [<Dorayakis: Dorayakis object (10)>,
<Dorayakis: Dorayakis object (11)>,
<Dorayakis: Dorayakis object (12)>]>
# 8の結果
<class 'django.db.models.fields.related_descriptors.
create_reverse_many_to_one_manager.<locals>.RelatedManager'>
# 9の結果
['__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', 'alias', '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']
“model_app/models.py"において,どちらのクラスでも,「クラスインスタンス名.フィールド名」を利用する.
なお,"extract_val.py"は以下のように編集する.
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE','model_project.settings')
from django import setup
setup()
from model_app.models import Places, Companies
# 1の処理(first:テーブルの1番最初の値)
p1 = Places.objects.first()
print(p1)
# 2の処理
print(type(p1))
# 3の処理
print(dir(p1))
# 4の処理
print(p1.name)
# 5の処理
print(p1.companies.name)
# 6の処理
c1 = Companies.objects.last()
print(c1.name)
■実行結果
# 1の結果
Places object (1)
# 2の結果
<class 'model_app.models.Places'>
# 3の結果
['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_default_pk',
'_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_expr_references',
'_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', '_prepare_related_fields_for_save',
'_save_parents', '_save_table', '_set_pk_val', '_state', 'address',
'check', 'clean', 'clean_fields', 'companies', 'date_error_message',
'delete', 'from_db', 'full_clean', 'get_deferred_fields', 'id', 'name',
'objects', 'pk', 'prepare_database_save', 'refresh_from_db', 'save',
save_base', 'serializable_value', 'unique_error_message', 'validate_unique']
# 4の結果
Kawasaki
# 5の結果
JFE Steel
# 6の結果
KOBE Steel
“model_app/models.py"において,"ManyToMany"が含まれているクラスの場合,「クラスインスタンス名.フィールド名」を利用し,"ManyToMany"が含まれていないクラスの場合,「クラスインスタンス名.フィールド名_set.all()」を利用する.
なお,"extract_val.py"は以下のように編集する.
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE','model_project.settings')
from django import setup
setup()
from model_app.models import Musics, Musicians
# 1の処理
m_cs = Musicians.objects.first()
print(m_cs.musics.all())
# 2の処理
print(type(m_cs))
# 3の処理
print(dir(m_cs))
# 4の処理
m_ans = Musics.objects.first()
print(m_ans.musicians_set.all())
■実行結果
# 1の結果
<QuerySet [<Musics: Tokyo Gird>, <Musics: Life Is a Flower>]>
# 2の結果
<class 'model_app.models.Musicians'>
# 3の結果
['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_default_pk',
'_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_expr_references',
'_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', '_prepare_related_fields_for_save', '_save_parents',
'_save_table', '_set_pk_val', '_state', 'check', 'clean', 'clean_fields',
'date_error_message', 'delete', 'from_db', 'full_clean', 'get_deferred_fields',
'id', 'musics', 'name', 'objects', 'pk', 'prepare_database_save',
'refresh_from_db', 'save', 'save_base', 'serializable_value',
'unique_error_message', 'validate_unique']
# 4の結果
<QuerySet [<Musicians: Ace of Base>]>
以上