2009-08-27 14 views
11

Trong models.py của tôi có một cái gì đó như:Làm thế nào để thêm nhiều hướng-đaaltanyfields trong django admin?

class LocationGroup(models.Model): 
    name = models.CharField(max_length=200) 

class Report(models.Model): 
    name = models.CharField(max_length=200) 
    locationgroups = models.ManyToManyField(LocationGroup) 

admin.py (tiêu chuẩn):

admin.site.register(LocationGroup) 
admin.site.register(Report) 

Khi tôi vào trang quản trị cho Báo cáo, nó cho thấy một lĩnh vực nhiều lựa chọn thoải mái. Làm cách nào để thêm cùng một trường đa lựa chọn trong LocationGroup? Tôi có thể truy cập vào tất cả các báo cáo bằng cách gọi LocationGroup.report_set.all()

+0

Vé liên quan: https://code.djangoproject.com/ticket/897 – guettli

Trả lời

8

Cách giải quyết tôi tìm thấy là làm theo hướng dẫn cho ManyToManyFields with intermediary models. Mặc dù bạn không sử dụng tính năng mô hình 'qua', chỉ cần giả vờ như thể bạn và tạo ra một mô hình sơ khai với ForeignKey cần thiết.

# models: make sure the naming convention matches what ManyToManyField would create 
class Report_LocationGroups(models.Model): 
    locationgroup = models.ForeignKey(LocationGroup) 
    report = models.ForeignKey(Report) 

# admin 
class ReportInline(admin.TabularInline): 
    model = models.Report_LocationGroups 

class LocationGroupAdmin(admin.ModelAdmin): 
    inlines = ReportInline, 
+1

Trông như triển khai dễ nhất tương đối, thx! –

+0

Dễ nhất, nhưng vẫn là một hack. Tôi muốn Django có thể hỗ trợ điều này là một cách thanh lịch hơn. –

2

Tôi nghĩ yon có thể kết hợp mẫu mã này (source) phá vỡ Mà sync_db

class ItemType(meta.Model): 
    name = meta.CharField(maxlength=100) 
    description = meta.CharField(maxlength=250) 
    properties = meta.ManyToManyField('PropertyType', 
      db_table='app_propertytype_itemtypes') 

class PropertyType(meta.Model): 
    name = meta.CharField(maxlength=100) 
    itemtypes = meta.ManyToManyField(ItemType) 

với this snippet

class ManyToManyField_NoSyncdb(models.ManyToManyField): 
    def __init__(self, *args, **kwargs): 
     super(ManyToManyField_NoSyncdb, self).__init__(*args, **kwargs) 
     self.creates_table = False 

để có được một cái gì đó như

class ItemType(meta.Model): 
    name = meta.CharField(maxlength=100) 
    description = meta.CharField(maxlength=250) 
    properties = meta.ManyToManyField_NoSyncdb('PropertyType', 
      db_table='app_propertytype_itemtypes') 

class PropertyType(meta.Model): 
    name = meta.CharField(maxlength=100) 
    itemtypes = meta.ManyToManyField(ItemType) 

Disclaimer: đây chỉ là một ý tưởng thô

Edit: Có lẽ là someting để làm với Django's 1.1 Proxy Models

1

Tôi nghĩ rằng những gì được bạn đang tìm kiếm là admin inlines. Trong admin.py của bạn, bạn sẽ muốn thêm một cái gì đó như thế này:

class LocationGroupInline(admin.TabularInline): 
    model = LocationGroup 

class ReportAdmin(admin.ModelAdmin): 
    inlines = [ LocationGroupInline, ] 
admin.site.register(Report, ReportAdmin) 
admin.site.register(LocationGroup) 

Có nhiều tùy chọn để bao gồm trong LocationGroupInline nếu bạn muốn cấu hình thêm hiển thị nội tuyến của mô hình liên quan. Hai trong số các tùy chọn này là biểu mẫuformset, cho phép bạn sử dụng các biểu mẫu Django Form và FormSet tùy chỉnh để tùy chỉnh thêm giao diện của quản trị viên mô hình nội tuyến. Sử dụng điều này bạn có thể tạo một Form đơn giản chỉ hiển thị trường chọn lựa mà bạn muốn (ngoại trừ trường M2M nó sẽ không thể hiển thị dưới dạng một menu thả xuống, mà là một hộp chọn nhiều). Ví dụ:

class MyLocationGroupForm(forms.Form): 
    location = forms.MultipleModelChoiceField(
      queryset=LocationGroup.objects.all()) 

class LocationGroupInline(admin.TabularInline): 
    model = LocationGroup 
    form = MyLocationGroupForm 
+1

Báo cáo quản trị sẽ có vị trí Nhóm được gạch chân theo mặc định, câu hỏi là cách thực hiện ngược lại. Bất kể, điều này sẽ làm tăng một ngoại lệ mà LocationGroup không có ForeignKey để ReportAdmin. –

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