2009-06-20 11 views
14

Tôi muốn thêm một trường vào mô hình cơ sở dữ liệu FlatPage Django, nhưng tôi thực sự không biết cách mở rộng mà không cần chỉnh sửa ứng dụng gốc.Thêm chức năng vào Django FlatPages mà không thay đổi Django App gốc

Những gì tôi muốn làm là để thêm các lĩnh vực sau vào mô hình:


from django.db import models 
from django.contrib.flatpages.models import FlatPage as FlatPageOld 

class FlatPage(FlatPageOld): 
    order = models.PositiveIntegerField(unique=True) 

Làm thế nào để tôi nhận được để thêm video này vào mô hình FlatPage?

Cảm ơn trước

Trả lời

20

Cách tiếp cận của bạn tốt - bạn chỉ không thấy kết quả vì mô hình flatpage cũ được đăng ký trong quản trị viên và mô hình mới chưa được đăng ký. Dưới đây là những gì bạn có thể làm trong admin.py ứng dụng mới của bạn (sử dụng đặt tên ít mơ hồ hơn những gì bạn đã có ở trên):

from django.contrib import admin 
from django.contrib.flatpages.admin import FlatPageAdmin 
from django.contrib.flatpages.forms import FlatpageForm 
from django.contrib.flatpages.models import FlatPage 

from models import ExtendedFlatPage 

class ExtendedFlatPageForm(FlatpageForm): 
    class Meta: 
     model = ExtendedFlatPage 

class ExtendedFlatPageAdmin(FlatPageAdmin): 
    form = ExtendedFlatPageForm 
    fieldsets = (
     (None, {'fields': ('url', 'title', 'content', 'sites', 'order')}), 
    )  

admin.site.unregister(FlatPage) 
admin.site.register(ExtendedFlatPage, ExtendedFlatPageAdmin) 

Rõ ràng là có một vài điều xảy ra ở đây, nhưng quan trọng nhất là mô hình FlatPage là không được đăng ký và mô hình ExtendedFlatPage đang được đăng ký tại chỗ của nó.

+0

Cảm ơn rất nhiều! Tôi đoán đây là những gì tôi đang tìm kiếm. –

+8

Hãy nhớ rằng cách tiếp cận này sẽ không hoạt động với FlatpageFallbackMiddleware mặc định - nó sẽ trả về các phiên bản của mô hình Flatpage gốc, không phải là phần mở rộng của bạn. Vì vậy, bạn sẽ phải viết phiên bản của riêng bạn, hoặc sử dụng URL/chế độ xem của riêng bạn. Ngoài ra, bây giờ bạn đã có hai bảng mà thực sự chỉ có một là cần thiết, mà kết quả trong các truy vấn ít hiệu quả.Tất cả trong tất cả, tôi khuyên bạn nên viết ứng dụng flatpage của riêng bạn từ đầu, hoặc sử dụng cách tiếp cận class_prepared để monkeypatch trường trong, thay vì sử dụng thừa kế. –

7

Và phương pháp trong bài đăng của bạn không hoạt động vì ...?

Nếu vì một số lý do bạn thực sự cần phải fiddle với lớp FlatPage dựng sẵn và chỉnh sửa nó tự động, bạn có thể treo vào tín hiệu class_prepared:

http://docs.djangoproject.com/en/dev/ref/signals/#class-prepared

Sửa

Dưới đây là cách bạn thực hiện với class_prepared:

from django.db.models.signals import class_prepared 
from django.db import models 

def alter_flatpages(sender, **kwargs): 
    if sender.__module__ == 'django.contrib.flatpages.models' and sender.__name__ == 'FlatPage': 
     order = models.IntegerField() 
     order.contribute_to_class(sender, 'order') 

class_prepared.connect(alter_flatpages) 

Đặt điều này vào, ví dụ: 'signals.py' trong cùng thư mục với settings.py của bạn và thêm 'tín hiệu' vào đầu (điều này quan trọng, để đảm bảo trình xử lý tín hiệu được cài đặt đúng lúc) danh sách INSTALLED_APPS.

Tuy nhiên, điều này vẫn không nhận được trường được hiển thị trong Quản trị viên, bởi vì có một lớp ModelAdmin tùy chỉnh cho Trang tính liệt kê rõ ràng các trường. Vì vậy, sau khi nó được đăng ký trong các ứng dụng flatpages, bạn cần phải hủy đăng ký nó ở đâu đó (admin.site.unregister) và đăng ký một ModelAdmin của riêng bạn.

+0

Trường này không hiển thị trong quản trị viên? Tôi không hiểu tại sao. Đó là vấn đề –

+0

Cũng không có lý do gì nên hiển thị trong quản trị viên cho lớp Django được xây dựng - bạn chưa sửa đổi nó! Nếu bạn tạo FlatPage của riêng mình, trong một ứng dụng riêng biệt, bạn cần phải đăng ký lớp học mới của mình với quản trị viên. Nếu bạn không muốn làm điều đó, bạn có thể đi theo cách class_prepared, nhưng điều này giả định một số kiến ​​thức khá tốt về Python. – oggy

+0

Hmm ok, tôi nghĩ rằng tôi sẽ có thể monkeypatch lớp FlatPage ban đầu để nó thực sự sẽ hiển thị trong admin mà không cần tạo một ứng dụng mới (và các mô hình). Bạn có thể đưa ra một ví dụ về cách class_prepared? –