2011-02-03 39 views
12

Tôi muốn tạo một số cài đặt toàn cầu của Django có thể cấu hình thông qua giao diện quản trị.Mô hình Django: Chỉ cho phép một mục nhập trong một mô hình?

Để kết thúc đó, tôi đã quyết định đặt chúng làm trường cơ sở dữ liệu, thay vì trong settings.py.

Đây là các thiết lập tôi quan tâm:

class ManagementEmail(models.Model): 
    librarian_email = models.EmailField() 
    intro_text = models.CharField(max_length=1000) 
    signoff_text = models.CharField(max_length=1000) 

Đây là một lần thiết lập toàn cầu, vì vậy tôi chỉ bao giờ muốn có được một đơn librarian_email, intro_text vv nổi xung quanh hệ thống.

Có cách nào để ngăn người dùng quản trị thêm bản ghi mới tại đây, mà không ngăn họ chỉnh sửa bản ghi hiện tại không?

Tôi đoán tôi có thể làm điều này bằng cách viết mẫu quản trị tùy chỉnh cho mô hình này, nhưng tôi muốn biết liệu có cách nào khác để định cấu hình này không.

Tôi có thể sử dụng thứ gì đó khác ngoài class không?

Cảm ơn!

Trả lời

14

Xin xem this question on "keep[ing] settings in database", nơi mà các câu trả lời có vẻ là django-dbsettings

Cập nhật

Chỉ cần nghĩ đến một tùy chọn: bạn có thể tạo ra các mô hình sau:

from django.contrib.sites.models import Site 

class ManagementEmail(models.Model): 
    site = models.OneToOneField(Site) 
    librarian_email = models.EmailField() 
    intro_text = models.CharField(max_length=1000) 
    signoff_text = models.CharField(max_length=1000) 

Do lĩnh vực OneToOneField, bạn chỉ có thể có một bản ghi ManagementEmail trên mỗi trang web. Sau đó, chỉ cần chắc chắn rằng bạn đang sử dụng các trang web và sau đó bạn có thể kéo các thiết lập thusly:

from django.contrib.sites.models import Site 
managementemail = Site.objects.get_current().managementemail 

Lưu ý rằng những gì người khác đang nói với bạn là đúng; nếu mục tiêu của bạn là lưu trữ cài đặt, hãy thêm chúng từng cái một dưới dạng trường vào mô hình không phải là triển khai tốt nhất. Thêm cài đặt theo thời gian sẽ là một nhức đầu: bạn phải thêm trường vào mô hình của mình, cập nhật cấu trúc cơ sở dữ liệu và sửa đổi mã đang gọi cài đặt đó.

Đó là lý do tại sao tôi khuyên bạn nên sử dụng ứng dụng django tôi đã đề cập ở trên, vì nó thực hiện chính xác những gì bạn muốn - cung cấp cho người dùng có thể chỉnh sửa cài đặt - mà không làm cho bạn làm thêm.

+0

Cảm ơn. Tôi là một chút cảnh giác với django-dbsettings, đưa ra các bình luận từ các nhà phát triển ở đây: http://www.chicagodjango.com/blog/django-settings-database/ – AP257

+0

Âm thanh như khiếu nại của mình về django-dbsettings sẽ không áp dụng trong trường hợp của bạn. Bạn đang xác định tất cả các cài đặt trong mã. Tôi chắc chắn sẽ khuyên bạn nên chống lại viết Singleton của riêng bạn để xử lý này. –

+0

Đó là nhận xét của nhà phát ngôn nói rằng anh ấy không còn duy trì nó làm tôi lo lắng nữa. Thật vậy, khi tôi cố gắng cài đặt nó, tôi bắt đầu nhận được lỗi về 'newforms', cho thấy nó khá lạc hậu ... sẽ thử gợi ý thay thế của bạn, cảm ơn! – AP257

2

Chỉ cần thiết lập ứng dụng GlobalSettings hoặc nội dung nào đó với trường Khóa và giá trị.

Bạn có thể dễ dàng ngăn người dùng quản trị thay đổi giá trị bằng cách không cho phép họ chỉnh sửa ứng dụng GlobalSettings.

class GlobalSettingsManager(models.Manager): 
     def get_setting(self, key): 
      try: 
       setting = GlobalSettings.objects.get(key=key) 
      except: 
       raise MyExceptionOrWhatever 
      return setting 

class GlobalSettings(models.Model): 
     key = models.CharField(unique=True, max_length=255) 
     value = models.CharField(max_length=255) 

     objects = GlobalSettingsManager() 

>>> APP_SETTING = GlobalSettings.objects.get_setting('APP_SETTING') 

Có các ứng dụng cho điều này nhưng tôi thích xem chúng và tự viết.

+0

Có, tôi cũng thích thứ gì đó trong db hơn là một ứng dụng. BAO GIỜ: như đã nêu trong câu hỏi, người dùng quản trị * có thể chỉnh sửa * các trường hiện tại - không thể thêm các mục mới. Có suy nghĩ gì không? – AP257

2

Tôi muốn tham gia một trang ra khỏi wordpress và tạo một mô hình cài đặt hỗ trợ đó.

class Settings(model.models): 
option_name = models.charfield(max_length = 1000) 
option_value = models.charfield(max_length = 25000) 
option_meta = models.charfield(max_length = 1000) 

Sau đó, bạn có thể chỉ cần pickle (serialize) các đối tượng vào các trường và bạn sẽ vững chắc.

Tạo một chút api và bạn có thể xảo quyệt như wordpress và gọi. AdminOptions.get_option(opt_name)

Sau đó, bạn chỉ có thể tải cài đặt tùy chỉnh vào thời gian chạy, giữ riêng biệt mô-đun settings.py nhưng bằng nhau. Một nơi tốt để viết điều này sẽ có trong một tập tin __init__.py.

9

Tôi nghĩ rằng cách dễ nhất bạn có thể làm điều này là sử dụng has_add_permissions chức năng của ModelAdmin:

class ContactUsAdmin(admin.ModelAdmin): 
    form = ContactUsForm 

    def has_add_permission(self, request): 
     return False if self.model.objects.count() > 0 else super().has_add_permission(request) 

Bạn có thể đặt ở trên để được bất kỳ số nào bạn thích, xem django docs.

Nếu bạn cần chi tiết hơn mức đó và làm cho lớp trở thành một singleton ở cấp mô hình, hãy xem django-solo. Có rất nhiều triển khai singleton cũng mà tôi đã đi qua.

Đối StackedInline, bạn có thể sử dụng MAX_NUM = 1.

+1

Tôi nghĩ 'return False nếu self.model.objects.count()> 0 else super(). Has_add_permission (request)' sẽ tốt hơn về các quy tắc quản lý quyền. –

+0

Có một lỗi nếu bạn xóa các mục nhập duy nhất, điều này làm việc tốt hơn 'nếu self.model.objects.count()> 0: \t \t \t trở False \t \t khác: \t \t \t trở TRUE' – paul100

+0

Nếu nó trả về 0, nó sẽ đánh giá 'super(). has_add_permission (yêu cầu)' và trả về lỗi nếu không có quyền, điều đó nghe đúng. – radtek

0

Sửa đổi câu trả lời @radtek để ngăn chặn xóa nếu chỉ có một lối vào được trái

class SendgridEmailQuotaAdmin(admin.ModelAdmin): 
    list_display = ('quota','used') 
    def has_add_permission(self, request): 
     return False if self.model.objects.count() > 0 else True 
    def has_delete_permission(self, request, obj=None): 
     return False if self.model.objects.count() <= 1 else True 
    def get_actions(self, request): 
     actions = super(SendgridEmailQuotaAdmin, self).get_actions(request) 
     if(self.model.objects.count() <= 1): 
      del actions['delete_selected'] 
     return actions 
0

tôi đã cơ bản cùng một vấn đề như các poster ban đầu mô tả, và nó dễ dàng cố định bằng cách ghi đè lớp modelAdmin. Một cái gì đó tương tự như sau trong một tập tin admin.py dễ dàng ngăn chặn thêm một đối tượng mới nhưng cho phép chỉnh sửa hiện thời:

class TitleAdmin(admin.ModelAdmin): 
def has_delete_permission(self, request, obj=TestModel.title): 
    return False 

def has_add_permission(self, request): 
    return False 

def has_change_permission(self, request, obj=TestModel.title): 
    return True 

này không ngăn cản một người dùng đăng một hình thức mà chỉnh sửa dữ liệu, nhưng giữ những điều xảy ra trong trang Quản trị. Tùy thuộc vào việc bạn có cảm thấy cần thiết cho nhu cầu của mình hay không, bạn có thể cho phép xóa và thêm bản ghi với mức tối thiểu của mã hóa.

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