I have been trying to define custom django model field in python. I referred the django docs at following location https://docs.djangoproject.com/en/1.10/howto/custom-model-fields/. However, I am confused over the following methods(which I have divided into groups as per my understanding) :-
Group 1 (Methods in this group are inter-related as per docs)
__init__
()- deconstruct()
Group 2
- db_type()
- rel_db_type()
- get_internal_type()
Group 3
- from_db_value()
- to_python()
- get_prep_value()
- get_db_prep_value()
- get_db_prep_save()
- value_from_object()
- value_to_string()
Group 4
- formfield
I am having following questions :-
When
deconstruct()
is used ? Docs says that, it's useful during migration, but it's not clearly explained. Moreover, when is it called ?Difference between
db_type()
andget_internal_type()
- Difference between
get_prep_value()
andget_db_prep_value()
- Difference between
value_from_object()
andvalue_to_string()
.value_from_object()
is not given in docs. - Both
from_db_value()
,value_to_string()
andto_python()
gives python object from string. Then, why these different methods are exists ?
I know, I have asked a bit lengthy question. But couldn't find any other way to better ask this question.
Thanks in advance.
I'll try to answer them:
Q: When
deconstruct()
is used ?A: This method is being used when you have instance of your
Field
to re-create it based on arguments you just passed in__init__
. As they mentioned in docs, if you are settingmax_length
arg to a static value in your__init__
method; you do not need it for your instances. So you can delete it in yourdeconstruct()
method. With this,max_length
won't show up in your instance while you are using it in your models. You can thinkdeconstruct
as a last clean-up and control place before use your field in model.Q: Difference between
db_type()
andget_internal_type()
A: They are both related, but belong to different levels.
If your custom field's data type is depends on which DB you are using,
db_type()
is the place you can do your controls. Again, like they mentioned in docs, if your field is a kind of date/time value, you should / may check if current database isPostgreSQL
orMySQL
in this method. Because while date/time values called astimestamp
inPostgreSQL
, it is calleddatetime
inMySQL
.get_internal_type
method is kind of higher level version ofdb_type()
. Let's go over date/time value example: If you don't want to check and control each data types belongs to different databases, you can inherit your custom field's data type frombuilt-in
Django fields. Instead of checking if it should bedatetime
ortimestamp
; you can return simplyDateField
in yourget_internal_type
method. As they mentioned in docs, If you've createddb_type
method already, in most cases, you do not needget_internal_type
method.Q: Difference between
get_prep_value()
andget_db_prep_value()
A: These guys also share
almost
same logic betweendb_type()
andget_internal_type()
. First of all, both these methods stands for converting db values topython objects
. But, like indb_type
method,get_db_prep_value()
stands forbackend
specific field types.Q: Difference between
value_from_object()
andvalue_to_string()
.value_from_object()
is not given in docsA: From the docs:
So, Actually we don't need
value_from_object
as documented. This method is used to get field's raw value before serialization. Get the value with this method, and customize how it should be serialized invalue_to_string
method. They even put an example code in docsQ: Both
from_db_value()
,value_to_string()
andto_python()
gives python object from string. Then, why these different methods are exists ?A: While
to_python()
converts field value to a valid python object,value_to_string()
converts field values to string with your custom serialization. They stands for different jobs.And
from_db_value
converts the value returned by database to python object. Never heard of it actually. But check this part from docs: