2016-03-02 17 views
7

Tôi có một số hành vi kỳ lạ, ít nhất là đối với tôi, điều đó đang gây ra cho tôi một số lỗi trong dự án của tôi.Tại sao thuộc tính related_model của Django lại trả về chuỗi thay vì kiểu mẫu?

Tôi đang sử dụng Django 1.9 và gói django bên thứ ba (django-jet) sử dụng tài sản field.related_model trong quản trị Django và đôi khi không thành công vì yêu cầu field.related_model trả về phiên bản mẫu và một số mô hình của tôi trả về tên mẫu .

This is the property defined in Django code:

@cached_property 
def related_model(self): 
    # Can't cache this property until all the models are loaded. 
    apps.check_models_ready() 
    return self.remote_field.model 

Những điều mà tôi đã cố gắng:

  • Nếu related_model Django là một @property thay vì một @cached_property nó hoạt động và trả về Ví dụ mô hình.
  • Nếu tôi gọi field.remote_field.model thay vì field.related_model trong dòng gây ra lỗi hoạt động và trả về phiên bản mẫu.

Xin vui lòng, bạn có ý tưởng gì không? Tôi có thể giải quyết vấn đề này nhưng tôi muốn biết lý do tại sao hành vi này.

Cảm ơn trước!

Trả lời

2

Tôi nghĩ rằng vấn đề ở đây phát sinh do máy bay phản lực đang cố gắng sử dụng related_model theo phương pháp RelatedFieldAjaxListFilter.field_choices() và điều này có thể được thực hiện trước khi tất cả các ứng dụng đã được tải. Nếu tôi hiểu chính xác, giá trị related_model ban đầu là một chuỗi, được thay thế bằng một đối tượng mô hình trong quá trình khởi tạo mô hình. Nếu bạn cố gắng nhận được giá trị đó trước khi các ứng dụng đã tải xong, bạn có thể nhận được một chuỗi hoặc một đối tượng, tùy thuộc vào thứ tự các mô hình được tải. Và, vì đó là thuộc tính được lưu trong bộ nhớ cache, việc nhận giá trị chuỗi ở giai đoạn đó sẽ khiến giá trị chuỗi được lưu vào bộ nhớ cache. Xem, ví dụ, nhận xét trong django.db.models.options,

# The mechanism for getting at the related model is slightly odd - 
# ideally, we'd just ask for field.related_model. However, related_model 
# is a cached property, and all the models haven't been loaded yet, so 
# we need to make sure we don't cache a string reference. 

Bằng cách làm cho một tài sản related_name uncached, bạn tránh được vấn đề đó.

Trong mã django.contrib.admin.filters.RelatedFieldListFilter, chúng KHÔNG sử dụng related_model để lấy đối tượng mô hình, nhưng thay vào đó sử dụng hàm tiện ích, django.contrib.admin.utils.get_model_from_relation(). Các RelatedFieldAjaxListFilter.field_choices() có lẽ nên làm một cái gì đó tương tự.

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