2010-05-02 34 views
7

我想在我的django應用程序的每個模型中添加幾個字段。這次是created_at,updated_atnotes。爲20多個模型中的每一個複製代碼似乎都很愚蠢。所以,我決定使用可以添加這些字段的抽象基類。問題是,從抽象基類繼承的字段在管理中的字段列表中首先出現。爲每個ModelAdmin類聲明字段順序不是一個選項,它比手動字段聲明更重複的代碼。在Django模型中重新排序字段

在我最後的解決辦法,我修改了模型構建創建新實例之前,重新排序_meta領域:

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 ... 

它按預期工作,但我想知道,有沒有更好的方式來acheive我的目標?

回答

5

如果您主要需要爲Django的管理員訂購,還可以通過對Django的管理員類進行子分類來創建您的「通用」-admin類。請參閱http://docs.djangoproject.com/en/dev/intro/tutorial02/#customize-the-admin-form以自定義管理員中字段的顯示。 您可以根據需要覆蓋管理員的__init__以設置創建管理實例時的字段/字段集。例如。你可以這樣做:

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) 

除此之外,我認爲這不是修改(私人)_field_name_cache一個很好的做法!

7

我有非常相同的問題,但我發現這些解決方案是有問題的,所以這是我做的:

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 

更改在管理字段集更有意義對我來說,不是改變場在模型中。

0

我也不喜歡其他解決方案,所以我只是直接修改了遷移文件。

每當你在models.py中創建一個新表,你將不得不運行「python manage.py makemigrations」(我相信這在Django> = v1.7.5中)。一旦你這樣做,打開新創建的遷移文件your_app_path/migrations/目錄,並簡單地將行移動到你想要的順序。然後運行「python manage.py migrate」。瞧!通過進入「python manage.py dbshel​​l」,你可以看到列的順序正是你想要它們的方式!

該方法的缺點:您必須爲每個創建的表手動執行此操作,但幸運的是開銷很小。這隻能在創建新表時完成,而不能修改現有的表。