2012-08-10 31 views
5

Tôi đang viết ứng dụng Django đầu tiên của mình. Tôi có mô hình cơ sở dữ liệu sau:Django Admin: tự động tạo nhiều dòng nội tuyến với cùng một kiểu

class Person(models.Model): 
    first_name   = models.CharField(max_length = 100) 
    last_name   = models.CharField(max_length = 100) 

class InformationType(models.Model): 
    name = models.CharField(max_length = 100) 

class Information(models.Model): 

    person  = models.ForeignKey(Person) 
    info_type = models.ForeignKey(InformationType) 
    info   = models.CharField(max_length = 200) 

Tôi muốn tạo nhiều nội tuyến trong Quản trị Django (lớp PersonAdmin (ModelAdmin)) bằng cách tách mô hình thông tin theo loại và tự động làm. Ngoài ra tôi muốn ẩn (loại trừ) lĩnh vực 'info_type' từ giao diện người dùng và tự động điền nó với giá trị tương ứng.

Tôi có thể tạo động nội tuyến với dữ liệu 'Thông tin' được lọc bởi 'info_type' nhưng ẩn trường này trong giao diện người dùng khiến nó trống khi lưu.

Tôi có thể làm như thế nào? Có thể tạo ra trường ẩn? Hoặc tôi nên lưu trữ giá trị 'info_type' ở đâu?

Tôi đã googled cứng và tìm thấy điều gì =)

Nối: OK. Tôi đã sửa đổi 'Thông tin' lớp:

class Information(models.Model): 

    def save(self, *args, **kwargs): 
     self.info_type = self.fixed_info_type 
     super(Information, self).save(*args, **kwargs) 

... và đánh dấu vài proxy:

class InformationManager(models.Manager): 

    def __init__(self, info_type, *args, **kwargs): 
     self.__info_type = info_type 
     super(InformationManager, self).__init__(*args, **kwargs) 

    def get_query_set(self, *args, **kwargs): 
     return super(self.__class__, self).get_query_set(*args, **kwargs).filter(info_type=self.__info_type) 

class PhoneInformation(Information): 

    fixed_info_type = 'PHONE' 
    objects = InformationManager(fixed_info_type) 
    class Meta: 
     proxy = True 

class EmailInformation(Information): 

    fixed_info_type = 'EMAIL' 
    objects = InformationManager(fixed_info_type) 
    class Meta: 
     proxy = True 

trong admin.py:

from contacts.models import Person, PhoneInformation, EmailInformation 
class PersonAdmin(admin.ModelAdmin): 
    __inlines = [] 

    class classproperty(property): 
     def __get__(self, instance, owner): 
      return super(self.__class__, self).fget.__get__(None, owner)() 

    @classproperty  
    @classmethod 
    def inlines(cls): 

     def get_inline(InformationModel): 
      class Inline(admin.TabularInline): 
       model = InformationModel 
       exclude= ['info_type'] 

      return Inline 

     if not cls.__inlines: 
      for InformationModel in [PhoneInformation, EmailInformation]: 
       cls.__inlines.append(get_inline(InformationModel)) 
     return cls.__inlines 

Vì vậy, nó trông xấu xí và don' phù hợp với nguyên tắc DRY. Tôi không thể tạo proxy giống như InlineAdmin. Nó quay trở lại cùng một đối tượng mỗi lần.

Trả lời

1

Tôi đã tìm thấy giải pháp. Bây giờ tôi có thể tạo các mô hình proxy động khi đang di chuyển. models.py:

class Person(models.Model): 
    first_name   = models.CharField(max_length = 100) 
    last_name   = models.CharField(max_length = 100) 

class InformationType(models.Model): 
    class Meta: 
     ordering = ['order'] 

    name = models.CharField(max_length = 200) 
    order = models.IntegerField() 

class Information(models.Model): 

    person  = models.ForeignKey(Person) 
    info_type = models.ForeignKey(InformationType) 
    value  = models.CharField(max_length = 200) 

    @classmethod  
    def getProxy(cls, info_type): 
     class InformationManager(models.Manager): 
      def get_query_set(self, *args, **kwargs): 
       return super(self.__class__, self).get_query_set(*args, **kwargs).filter(info_type = info_type) 

     def save(self, *args, **kwargs): 
      self.info_type = info_type 
      super(Information, self).save(*args, **kwargs) 

     class Meta: 
      proxy = True 

     return type(
        'Information'+str(info_type.pk), 
        (Information,), 
        { 
         'Meta': Meta, 
         'save': save, 
         '__module__': 'contacts.models', 
         'objects': InformationManager(), 

        } 
        ) 

trong admin.py:

class PersonAdmin(admin.ModelAdmin): 

    __inlines = [] 

    class classproperty(property): 
     def __get__(self, instance, owner): 
      return super(self.__class__, self).fget.__get__(None, owner)() 


    @classproperty  
    @classmethod 
    def inlines(cls): 
     def get_inline(info_model): 
      class Inline(admin.TabularInline): 
       model = info_model 
       exclude= ['info_type'] 
      return Inline 

     if not cls.__inlines: 
      for info_model in [Information.getProxy(info_type) for info_type in InformationType.objects.all()]: 
       cls.__inlines.append(get_inline(info_model)) 
     return cls.__inlines 
Các vấn đề liên quan