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
Fieldto re-create it based on arguments you just passed in__init__. As they mentioned in docs, if you are settingmax_lengtharg 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_lengthwon't show up in your instance while you are using it in your models. You can thinkdeconstructas 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 isPostgreSQLorMySQLin this method. Because while date/time values called astimestampinPostgreSQL, it is calleddatetimeinMySQL.get_internal_typemethod 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-inDjango fields. Instead of checking if it should bedatetimeortimestamp; you can return simplyDateFieldin yourget_internal_typemethod. As they mentioned in docs, If you've createddb_typemethod already, in most cases, you do not needget_internal_typemethod.Q: Difference between
get_prep_value()andget_db_prep_value()A: These guys also share
almostsame logic betweendb_type()andget_internal_type(). First of all, both these methods stands for converting db values topython objects. But, like indb_typemethod,get_db_prep_value()stands forbackendspecific 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_objectas 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_stringmethod. 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_valueconverts the value returned by database to python object. Never heard of it actually. But check this part from docs: