Reputation: 11420
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__
()Group 2
Group 3
Group 4
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()
and get_internal_type()
get_prep_value()
and get_db_prep_value()
value_from_object()
and value_to_string()
. value_from_object()
is not given in docs.from_db_value()
, value_to_string()
and to_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.
Upvotes: 4
Views: 2525
Reputation: 7917
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 setting max_length
arg to a static value in your __init__
method; you do not need it for your instances. So you can delete it in your deconstruct()
method. With this, max_length
won't show up in your instance while you are using it in your models. You can think deconstruct
as a last clean-up and control place before use your field in model.
Q: Difference between db_type()
and get_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 is PostgreSQL
or MySQL
in this method. Because while date/time values called as timestamp
in PostgreSQL
, it is called datetime
in MySQL
.
get_internal_type
method is kind of higher level version of db_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 from built-in
Django fields. Instead of checking if it should be datetime
or timestamp
; you can return simply DateField
in your get_internal_type
method. As they mentioned in docs, If you've created db_type
method already, in most cases, you do not need get_internal_type
method.
Q: Difference between get_prep_value()
and get_db_prep_value()
A: These guys also share almost
same logic between db_type()
and get_internal_type()
. First of all, both these methods stands for converting db values to python objects
. But, like in db_type
method, get_db_prep_value()
stands for backend
specific field types.
Q: Difference between value_from_object()
and value_to_string()
. value_from_object()
is not given in docs
A: From the docs:
To customize how the values are serialized by a serializer, you can override
value_to_string()
. Usingvalue_from_object()
is the best way to get the field’s value prior to serialization.
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 in value_to_string
method. They even put an example code in docs
Q: Both from_db_value()
, value_to_string()
and to_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:
This method is not used for most built-in fields as the database backend already returns the correct Python type, or the backend itself does the conversion.
Upvotes: 11