class Model
(**kwargs)
The keyword arguments are the names of the fields you’ve defined on your model. Note that instantiating a model in no way touches your database; for that, you need to save()
.
Model의 __init__을 이용해 Model이 생성될 때 어떤작업을 하고 싶은 경우 __init__을 override하는 것보다 . 아래와 같이 class method를 이용해 처리할것을 추천한다.
1. Add a classmethod on the model class:
from django.db import models class Book(models.Model): title = models.CharField(max_length=100) @classmethod def create(cls, title): book = cls(title=title) # do something with the book return book book = Book.create("Pride and Prejudice")
2. Add a method on a custom manager (usually preferred):
class BookManager(models.Manager): def create_book(self, title): book = self.create(title=title) # do something with the book return book class Book(models.Model): title = models.CharField(max_length=100) objects = BookManager() book = Book.objects.create_book("Pride and Prejudice")
Customizing model loading¶
Model이 loading될때 추가 작업을 하고싶은 경우 from_db()를 override한다.classmethod
Model.
from_db(db, field_names, values)
참고자료) https://www.webforefront.com/django/modelmethodsandmetaoptions.html 하단부
Refreshing objects from database¶
If you delete a field from a model instance, accessing it again reloads the value from the database:
>>> obj = MyModel.objects.first() >>> del obj.field >>> obj.field # Loads the field from the database
Model.
refresh_from_db(using=None, fields=None)
if you need to reload a model’s values from the database, you can use the refresh_from_db()
method.
Validating objects¶
There are three steps involved in validating a model:
- Validate the model fields –
Model.clean_fields()
- Validate the model as a whole –
Model.clean()
- Validate the field uniqueness –
Model.validate_unique()
All three steps are performed when you call a model’s full_clean()
method.
Model.
full_clean(exclude=None, validate_unique=True)
This method calls Model.clean_fields()
, Model.clean()
, and Model.validate_unique()
(if validate_unique
is True
) 유효성 검사중에 어디서든 ValidationError
raise되면 유효성검사가 실패한것이 된다.
The optional exclude
argument can be used to provide a list of field names that can be excluded from validation and cleaning. ModelForm
uses this argument to exclude fields that aren’t present on your form from being validated since any errors raised could not be corrected by the user.
Note that full_clean()
will not be called automatically when you call your model’s save()
method.
full_clean()의 호출방법의 예는 아래와 같다.
from django.core.exceptions import ValidationError try: article.full_clean() except ValidationError as e: # Do something based on the errors contained in e.message_dict. # Display them to a user, or handle them programmatically. pass
Model.
clean_fields(exclude=None)
This method will validate all fields on your model. The optional exclude
argument lets you provide a list of field names to exclude from validation. It will raise a ValidationError
if any fields fail validation.
The second step full_clean()
performs is to call Model.clean()
. This method should be overridden to perform custom validation on your model.
Model.
clean()
This method should be used to provide custom model validation, and to modify attributes on your model if desired. For instance, you could use it to automatically provide a value for a field, or to do validation that requires access to more than a single field: 아래와 같이 여러 항목을 이용해서 validate하는 경우 clean()에서 작업한다.
import datetime from django.core.exceptions import ValidationError from django.db import models from django.utils.translation import gettext_lazy as _ class Article(models.Model): ... def clean(self): # Don't allow draft entries to have a pub_date. if self.status == 'draft' and self.pub_date is not None: raise ValidationError(_('Draft entries may not have a publication date.')) # Set the pub_date for published items if it hasn't been set already. if self.status == 'published' and self.pub_date is None: self.pub_date = datetime.date.today()
To assign exceptions to a specific field, instantiate the ValidationError
with a dictionary, where the keys are the field names. 예를 들어 pub_date
field의 문제의 경우 아래와 같이 해준다.
class Article(models.Model): ... def clean(self): # Don't allow draft entries to have a pub_date. if self.status == 'draft' and self.pub_date is not None: raise ValidationError({'pub_date': _('Draft entries may not have a publication date.')})
Model.clean()에서 여러 에러가 발생하는 경우 아래와 같이
you can also pass a dictionary mapping field names to errors:
raise ValidationError({ 'title': ValidationError(_('Missing title.'), code='required'), 'pub_date': ValidationError(_('Invalid date.'), code='invalid'), })
ModelForm에서 Meta.fields
or Meta.exclude를 이용해 제외된 field의
ValidationError를 raise해도작동이 되지 않고 ValueError가 발생하게 되는데 이에 대한 우회방법은 아래와 같다.
To work around this dilemma, instead override Model.clean_fields()
as it receives the list of fields that are excluded from validation. For example:
class Article(models.Model): ... def clean_fields(self, exclude=None): #마치 제외된 field가 없는척한다. super().clean_fields(exclude=exclude) if self.status == 'draft' and self.pub_date is not None: if exclude and 'status' in exclude: raise ValidationError( _('Draft entries may not have a publication date.') ) else: raise ValidationError({ 'status': _( 'Set status to draft if there is not a ' 'publication date.' ), })
Model.
validate_unique
(exclude=None)
model의 field중에 unique
, unique_together
, unique_for_date|month|year 이 설정되있는 경우 호출되며 어떻게 unique를 결정할지에 대한 내용이 들어 간다.
Saving objects¶
To save an object back to the database, call save()
:
Model.
save(force_insert=False, force_update=False,using=DEFAULT_DB_ALIAS, update_fields=None)
Auto-incrementing primary keys
AutoField
— an auto-incrementing primary key — then that auto-incremented value will be calculated and saved as an attribute on your object the first time you call save()
:
>>> b2 = Blog(name='Cheddar Talk', tagline='Thoughts on cheese.') >>> b2.id # Returns None, because b2 doesn't have an ID yet. >>> b2.save() >>> b2.id # Returns the ID of your new object.
There’s no way to tell what the value of an ID will be before you call save()
For convenience, each model has an AutoField
named id
by default unless you explicitly specify primary_key=True
on a field in your model. See the documentation for AutoField
for more details. 특별히 특정 field에 primary_key=True 를 설정하지 않으면 id라는
AutoField 가 만들어 지게 된다.
Model.
pk
Model.
pk
자동으로 만들어진 AutoField이건 개발자가 primary_key=True 설정해 지정된 field이건 간에 간단히 pk 이름으로 접근할수 있다.
AutoField
로 정의 되어있더라도 개발자가 임의로 값을 할당할수 있다.
AutoField
이더라도 아래와 같이 처음 obj가 생성될때 넣어주면 이미 있지 않은 id라면 만들어진다. 이미 있던 id라면 내용이 update가 된다.
>>> b3 = Blog(id=3, name='Cheddar Talk', tagline='Thoughts on cheese.') >>> b3.id # Returns 3. >>> b3.save() >>> b3.id # Returns 3.
b4 = Blog(id=3, name='Not Cheddar', tagline='Anything but cheese.') b4.save() # Overrides the previous blog with ID=3!