2016-02-02 11 views
10

On nâng cấp lên Django 1.9, bây giờ tôi nhận được cảnh báoCách xử lý "SubfieldBase đã không được chấp nhận. Thay vào đó hãy sử dụng Field.from_db_value."

RemovedInDjango110Warning: SubfieldBase has been deprecated. Use Field.from_db_value instead. 

tôi nhìn thấy nơi mà vấn đề phát sinh. Tôi có một số định nghĩa trường tùy chỉnh và trong đó tôi có __metaclass__ = models.SubfieldBase. Ví dụ,

class DurationField(models.FloatField): 

    __metaclass__ = models.SubfieldBase 

    def __init__(self, *args, **kwargs): 

    ... 

Nếu tuyên bố __metaclass__ bị phản đối, những gì tôi phải thay thế nó bằng một cách chính xác?

Tôi chỉ lấy nó ra và thêm một phương pháp from_db_value như trong ví dụ ở đây: https://docs.djangoproject.com/en/1.9/howto/custom-model-fields/#converting-values-to-python-objects ?

Và cách from_db_valueto_python khác nhau? Cả hai dường như chuyển đổi dữ liệu cơ sở dữ liệu sang các đối tượng Python?

Trả lời

23

Vâng, bạn chỉ nên loại bỏ __metaclass__ dòng và thêm from_db_value()to_python():

class DurationField(models.FloatField): 

    def __init__(self, *args, **kwargs): 
     ... 

    def from_db_value(self, value, expression, connection, context): 
     ... 

    def to_python(self, value): 
     ... 

Như đã trình bày ở đây: https://docs.djangoproject.com/en/1.9/ref/models/fields/#field-api-reference, to_python(value) chuyển đổi giá trị (có thể là None, chuỗi hoặc đối tượng) vào đối tượng Python đúng.

from_db_value(value, expression, connection, context) chuyển đổi giá trị khi cơ sở dữ liệu trả về thành đối tượng Python.

Vì vậy, cả hai phương thức trả về các đối tượng Python, nhưng chúng được sử dụng bởi Django trong các tình huống khác nhau. to_python() được gọi bằng cách deserialization và trong phương pháp clean() được sử dụng từ các hình thức. from_db_value() được gọi khi dữ liệu được tải từ cơ sở dữ liệu

+1

đây là câu trả lời rất tốt và toàn diện. @mjandrews: tại sao bạn chưa đánh dấu nó là câu trả lời cuối cùng? – pt12lol

+0

Tôi thấy rằng không có metaclass, 'to_python' không phải lúc nào cũng được gọi. Ví dụ, nếu bạn tạo một thể hiện mới của một đối tượng và sau đó cố gắng đọc trường tùy chỉnh, nó sẽ không gọi các phương thức có metaclass mà nó đã gọi phương thức. –

Các vấn đề liên quan