장고 Model - ORM에서 사용하는 Field 리스트 살펴보기. 지속적으로 업데이트 중입니다! 오류 및 건의 사항은 댓글로 달아주세요! 장고 모델 - 필드 공식 문서 기준.
마지막 수정일: 23.03.31
class IntegerField(**options)
# ex
filed_name = IntegerField()
# chocies options 예시
class Card(models.Model):
class Suit(models.IntegerChoices):
DIAMOND = 1
SPADE = 2
HEART = 3
CLUB = 4
suit = models.IntegerField(choices=Suit.choices)
class BigIntegerField(**options)
# ex
filed_name = BigIntegerField()
class SmallIntegerField(**options)
# ex
filed_name = SmallIntegerField()
class AutoField(**options)
# ex
filed_name = AutoField()
class DecimalField(max_digits=None, decimal_places=None, **options)
# ex
filed_name = DecimalField(max_digits=5, decimal_places=3)
class FloatField(**options)
# ex
filed_name = FloatField()
class BooleanField(**options)
# ex
filed_name = BooleanField(default=False)
class CharField(max_length=None, **options)
# ex, 4글자 길이 제한
filed_name = CharField(max_length=4)
# inner class와 choice를 활용한 예시는 아래와 같다.
# 사실 정확하겐 java의 Enum과 비슷하게 사용하는 방법이다. (Enumeration types)
from django.utils.translation import gettext_lazy as _
class Student(models.Model):
class YearInSchool(models.TextChoices):
FRESHMAN = 'FR', _('Freshman')
SOPHOMORE = 'SO', _('Sophomore')
JUNIOR = 'JR', _('Junior')
SENIOR = 'SR', _('Senior')
GRADUATE = 'GR', _('Graduate')
year_in_school = models.CharField(
max_length=2,
choices=YearInSchool.choices,
default=YearInSchool.FRESHMAN,
)
def is_upperclass(self):
return self.year_in_school in {
self.YearInSchool.JUNIOR,
self.YearInSchool.SENIOR,
}
def is_upperclass(self)
와 같이 오버라이딩 해서 사용을 많이 한다. (특히 __str__
-> admin에서 보이는 값을 다르게 보여주기 때문)filed_name = models.CharField(validators=[RegexValidator(regex='^.{4}$', message='Length has to be 4', code='nomatch')])
class TextField(**options)
# ex
filed_name = TextField(max_length=4)
class URLField(max_length=200, **options)
# ex, max를 빼먹으면 기본적으로 200이 max
filed_name = URLField()
class EmailField(max_length=254, **options)
# ex, max를 빼먹으면 기본적으로 254이 max
filed_name = EmailField()
class SlugField(max_length=50, **options)
from django.utils.text import slugify
class Article(models.Model):
title = models.CharField(max_length=100)
slug = models.SlugField(unique=True)
def save(self, *args, **kwargs):
self.slug = slugify(self.title)
super(Article, self).save(*args, **kwargs)
# python manage.py shell
>>> test = Article.objects.create(title="django model field list")
>>> test.save()
>>> test.slug
"django-model-field-list"
class GenericIPAddressField(protocol='both', unpack_ipv4=False, **options)
# ex
filed_name = EmailField()
class UUIDField(**options)
# ex
import uuid
from django.db import models
class MyUUIDModel(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
# other fields
django-phonenumber-field
이다.pip install django-phonenumber-field
와 pip install phonenumbers
로 설치한다. 그리고 INSTALLED_APPS
에 'phonenumber_field'
를 추가한다.
아래와 같이 model field를 세팅한다.
from django.db import models
from phonenumber_field.modelfields import PhoneNumberField
class Contact(models.Model):
...
phone_number = PhoneNumberField(
verbose_name="관리자 전화번호",
help_text="가게 관리자 전화번호입니다.",
# region='US' 이렇게 특정 리전 고정도 가능
unique=True,
)
as_national_number
를 사용하면 아래와 같다.contact = Contact.objects.create(name='John', phone_number='+14155552671')
national_number = contact.phone_number.as_national_number() # returns '4155552671'
class DateField(auto_now=False, auto_now_add=False, **options)
# ex
created_at = models.DateField(auto_now_add=True)
updated_at = models.DateField(auto_now=True)
class DateTimeField(auto_now=False, auto_now_add=False, **options)
# ex
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class DurationField(**options)
# ex
time_passed = models.DurationField(default=timedelta())
class FileField(upload_to=None, max_length=100, **options)
# ex
# file will be uploaded to MEDIA_ROOT/uploads
upload = models.FileField(upload_to='uploads/')
# or...
# file will be saved to MEDIA_ROOT/uploads/2015/01/30
upload = models.FileField(upload_to='uploads/%Y/%m/%d/')
parser_classes = (MultiPartParser,)
와 같이 MultiPart Form으로 request를 받아야 한다. def user_directory_path(instance, filename):
# file will be uploaded to MEDIA_ROOT/user_<id>/<filename>
return 'user_{0}/{1}'.format(instance.user.id, filename)
class MyModel(models.Model):
upload = models.FileField(upload_to=user_directory_path)
위 예시에서 와 같이 upload_to에 함수를 할당해서 활용할 수 있다. 코드의 불필요한 반복이 줄어들고, file을 사용하는 부분의 upload_to를 따로 빼내서 관리가 가능하다. -> 변동 사항에 유동적으로 대응이 가능하다.
ps) For example, say your MEDIA_ROOT is set to '/home/media', and upload_to is set to 'photos/%Y/%m/%d'. The '%Y/%m/%d' part of upload_to is strftime() formatting. '%Y' is the four-digit year, '%m' is the two-digit month and '%d' is the two-digit day. If you upload a file on Jan. 15, 2007, it will be saved in the directory /home/media/photos/2007/01/15.
ps) 업로드된 파일이 수정가능하고 re-size를 하게 하려면 각각의 name과 size를 컬럼으로 만들어 저장하는 것을 추천한다. 그리고 option이 많으니 꼭 공식문서에서 더 자세하게 확인하자!!
class FilePathField(
path='', match=None, recursive=False,
allow_files=True, allow_folders=False,
max_length=100, **options
)
# ex
import os
from django.conf import settings
from django.db import models
def images_path():
return os.path.join(settings.LOCAL_FILE_DIR, 'images')
class MyModel(models.Model):
file = models.FilePathField(path=images_path)
FilePathField(path="/home/images", match="foo.*", recursive=True)
will match /home/images/foo.png but not /home/images/foo/bar.png because the match applies to the base filename (foo.png and bar.png).
FilePathField instances are created in your database as varchar columns with a default max length of 100 characters. -> As with other fields, you can change the maximum length using the max_length argument.
class ImageField(upload_to=None, height_field=None, width_field=None, max_length=100, **options)¶
# ex
photo = models.ImageField(upload_to='uploads/%Y/%m/%d/', blank=True)
class JSONField(encoder=None, decoder=None, **options)
# ex
data = models.JSONField(default='{}')
# 함수를 활용한 예시
def contact_default():
return {"email": "to1@example.com"}
contact_info = JSONField("ContactInfo", default=contact_default)
from django.db import models
class Dog(models.Model):
name = models.CharField(max_length=200)
data = models.JSONField(null=True)
def __str__(self):
return self.name
>>> Dog.objects.create(name='Max', data=None) # SQL NULL.
<Dog: Max>
>>> Dog.objects.create(name='Archie', data=Value('null')) # JSON null.
<Dog: Archie>
>>> Dog.objects.filter(data=None)
<QuerySet [<Dog: Archie>]>
>>> Dog.objects.filter(data=Value('null'))
<QuerySet [<Dog: Archie>]>
>>> Dog.objects.filter(data__isnull=True)
<QuerySet [<Dog: Max>]>
>>> Dog.objects.filter(data__isnull=False)
<QuerySet [<Dog: Archie>]>
None과 Value('null')을 저장한 두 object, model대상으로 filter로 None을 찾아보면 SQL NULL값은 찾아지지 않는다. 컬럼이름__isnull(sql에서 사용한는 isnull 쿼리를 하는 것)을 통해서 해당 Null을 찾을 수 있다.
SQL NULL 값으로 작업하려는 경우가 아니라면 null=False를 설정하고 빈 값에 적절한 기본값(예: default=default)을 제공하는 것이 좋다.
>>> Dog.objects.create(name='Rufus', data={
... 'breed': 'labrador',
... 'owner': {
... 'name': 'Bob',
... 'other_pets': [{
... 'name': 'Fishy',
... }],
... },
... })
<Dog: Rufus>
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': None})
<Dog: Meg>
>>> Dog.objects.filter(data__breed='collie')
<QuerySet [<Dog: Meg>]>
>>> Dog.objects.filter(data__owner__name='Bob')
<QuerySet [<Dog: Rufus>]>
>>> Dog.objects.filter(data__owner__other_pets__0__name='Fishy')
<QuerySet [<Dog: Rufus>]>
>>> Dog.objects.create(name='Shep', data={'breed': 'collie'})
<Dog: Shep>
>>> Dog.objects.filter(data__owner__isnull=True)
<QuerySet [<Dog: Shep>]>
# contains
>>> Dog.objects.create(name='Rufus', data={'breed': 'labrador', 'owner': 'Bob'})
<Dog: Rufus>
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})
<Dog: Meg>
>>> Dog.objects.create(name='Fred', data={})
<Dog: Fred>
>>> Dog.objects.filter(data__contains={'owner': 'Bob'})
<QuerySet [<Dog: Rufus>, <Dog: Meg>]>
>>> Dog.objects.filter(data__contains={'breed': 'collie'})
<QuerySet [<Dog: Meg>]>
# contained_by
>>> Dog.objects.create(name='Rufus', data={'breed': 'labrador', 'owner': 'Bob'})
<Dog: Rufus>
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})
<Dog: Meg>
>>> Dog.objects.create(name='Fred', data={})
<Dog: Fred>
>>> Dog.objects.filter(data__contained_by={'breed': 'collie', 'owner': 'Bob'})
<QuerySet [<Dog: Meg>, <Dog: Fred>]>
>>> Dog.objects.filter(data__contained_by={'breed': 'collie'})
<QuerySet [<Dog: Fred>]>
# has_key
>>> Dog.objects.create(name='Rufus', data={'breed': 'labrador'})
<Dog: Rufus>
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})
<Dog: Meg>
>>> Dog.objects.filter(data__has_key='owner')
<QuerySet [<Dog: Meg>]>
# has_keys
>>> Dog.objects.create(name='Rufus', data={'breed': 'labrador'})
<Dog: Rufus>
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})
<Dog: Meg>
>>> Dog.objects.filter(data__has_keys=['breed', 'owner'])
<QuerySet [<Dog: Meg>]>
# has_any_keys
>>> Dog.objects.create(name='Rufus', data={'breed': 'labrador'})
<Dog: Rufus>
>>> Dog.objects.create(name='Meg', data={'owner': 'Bob'})
<Dog: Meg>
>>> Dog.objects.filter(data__has_any_keys=['owner', 'breed'])
<QuerySet [<Dog: Rufus>, <Dog: Meg>]>
from django.db.models import Q
를 활용하는 방법은 공식문서에서 더 자세하게 살펴보자. class BinaryField(max_length=None, **options)
# ex
class GeeksModel(Model):
geeks_field = models.BinaryField()
# creating a bytes object
res = bytes(test_string, 'utf-8')
# creating a instance of
# GeeksModel
geek_object = GeeksModel.objects.create(geeks_field = res)
geek_object.save()
class ArrayField(base_field, size=None, **options)[source]
# ex
from django.contrib.postgres.fields import ArrayField
from django.db import models
class ChessBoard(models.Model):
board = ArrayField(
ArrayField(
models.CharField(max_length=10, blank=True),
size=8,
),
size=8,
)