2010-05-02 38 views
7

Tôi muốn thêm vài trường vào mọi mô hình trong ứng dụng django của mình. Lần này là created_at, updated_atnotes. Mã trùng lặp cho mỗi hơn 20 mô hình có vẻ câm. Vì vậy, tôi quyết định sử dụng lớp cơ sở trừu tượng sẽ thêm các trường này. Vấn đề là các trường được kế thừa từ lớp cơ sở trừu tượng đến đầu tiên trong danh sách trường trong admin. Khai báo thứ tự trường cho mỗi lớp ModelAdmin không phải là một tùy chọn, nó thậm chí còn nhiều mã trùng lặp hơn với khai báo trường thủ công.Sắp xếp lại các trường trong mô hình Django

Trong giải pháp cuối cùng của tôi, tôi sửa đổi constructor mô hình để sắp xếp lại các lĩnh vực trong _meta trước khi tạo thể hiện mới:

class MyModel(models.Model): 
    # Service fields 
    notes = my_fields.NotesField() 
    created_at = models.DateTimeField(auto_now_add=True) 
    updated_at = models.DateTimeField(auto_now=True) 

    class Meta: 
     abstract = True 

    last_fields = ("notes", "created_at", "updated_at") 
    def __init__(self, *args, **kwargs): 
     new_order = [f.name for f in self._meta.fields] 
     for field in self.last_fields: 
      new_order.remove(field) 
      new_order.append(field) 
     self._meta._field_name_cache.sort(key=lambda x: new_order.index(x.name)) 
     super(MyModel, self).__init__(*args, **kwargs) 

class ModelA(MyModel): 
    field1 = models.CharField() 
    field2 = models.CharField() 
    #etc ... 

Nó hoạt động như dự định, nhưng tôi đang tự hỏi, là có một cách tốt hơn để đạt được mục tiêu của tôi ?

Trả lời

5

Nếu bạn chủ yếu cần đặt hàng cho quản trị viên của Django, bạn cũng có thể tạo lớp "chung" -admin của bạn thông qua phân lớp quản trị của Django. Xem http://docs.djangoproject.com/en/dev/intro/tutorial02/#customize-the-admin-form để tùy chỉnh hiển thị các trường trong quản trị viên. Bạn có thể ghi đè lên số __init__ của quản trị viên để thiết lập các trường/trường vào việc tạo cá thể quản trị như bạn muốn. Ví dụ. bạn có thể làm một cái gì đó như:

class MyAdmin(admin.ModelAdmin): 
    def __init__(self, model, admin_site): 
     general_fields = ['notes', 'created_at', 'updated_at'] 
     fields = [f.name for f in self.model._meta.fields if f.name not in general_fields] 
     self.fields = fields + general_fields 
     super(admin.ModelAdmin, self).__init__(model, admin_site) 

Bên cạnh đó tôi nghĩ rằng không nên sửa đổi (riêng) _field_name_cache!

7

Tôi đã có những vấn đề rất giống nhau, nhưng tôi thấy các giải pháp này là có vấn đề, vì vậy đây là những gì tôi đã làm:

class BaseAdmin(admin.ModelAdmin): 
    def get_fieldsets(self, request, obj = None): 
     res = super(BaseAdmin, self).get_fieldsets(request, obj) 
     # I only need to move one field; change the following 
     # line to account for more. 
     res[0][1]['fields'].append(res[0][1]['fields'].pop(0)) 
     return res 

Thay đổi fieldset trong quản trị có ý nghĩa hơn đối với tôi, hơn là thay đổi các lĩnh vực trong mô hình.

0

Tôi C didn'tNG không thích các giải pháp khác, vì vậy thay vào đó tôi chỉ sửa đổi các tệp di chuyển một cách trực tiếp.

Bất cứ khi nào bạn tạo bảng mới trong models.py, bạn sẽ phải chạy "python manage.py makemigrations" (Tôi tin điều này trong Django> = v1.7.5). Khi bạn thực hiện việc này, hãy mở tệp di chuyển mới được tạo trong thư mục your_app_path/migrations/ và chỉ cần di chuyển các hàng theo thứ tự bạn muốn. Hãy chạy "python manage.py migrate". Thì đấy! Bằng cách vào "python manage.py dbshell", bạn có thể thấy rằng thứ tự của các cột chính xác như cách bạn muốn chúng!

Nhược điểm với phương pháp này: Bạn phải thực hiện việc này theo cách thủ công cho từng bảng mà bạn tạo, nhưng may mắn là chi phí tối thiểu. Và điều này chỉ có thể được thực hiện khi bạn đang tạo một bảng mới, không phải để sửa đổi một bảng hiện có.

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