2009-03-31 27 views
51

Tôi đã có một tập hợp các mô hình trông như thế này:Django admin - inlines inline (hoặc, ba mô hình chỉnh sửa cùng một lúc)

class Page(models.Model): 
    title = models.CharField(max_length=255) 

class LinkSection(models.Model): 
    page = models.ForeignKey(Page) 
    title = models.CharField(max_length=255) 

class Link(models.Model): 
    linksection = models.ForeignKey(LinkSection) 
    text = models.CharField(max_length=255) 
    url = models.URLField() 

và một admin.py trông như thế này:

class LinkInline(admin.TabularInline): 
    model = Link 
class LinkSectionInline(admin.TabularInline): 
    model = LinkSection 
    inlines = [ LinkInline, ] 
class PageAdmin(admin.ModelAdmin): 
    inlines = [ LinkSectionInline, ] 

Mục tiêu của tôi là có giao diện quản trị cho phép tôi chỉnh sửa mọi thứ trên một trang. Kết quả cuối cùng của cấu trúc mô hình này là những thứ được tạo thành một cái nhìn + mẫu trông nhiều hơn hoặc ít hơn như:

<h1>{{page.title}}</h1> 
{% for ls in page.linksection_set.objects.all %} 
<div> 
    <h2>{{ls.title}}</h2> 
    <ul> 
     {% for l in ls.link_set.objects.all %} 
     <li><a href="{{l.url}}">{{l.title}}</a></li> 
     {% endfor %} 
    </ul> 
</div> 
{% endfor %} 

Tôi biết rằng lừa inline-trong-một-inline thất bại trong admin Django, như Tôi mong đợi. Có ai biết cách để cho phép loại chỉnh sửa mô hình ba cấp này không? Cảm ơn trước.

+3

Bạn có thể hiển thị mã cuối cùng của mình với giải pháp bạn đã chấp nhận không? –

Trả lời

20

Bạn cần tạo một tùy chỉnh formtemplate cho số LinkSectionInline.

Something như thế này nên làm việc cho các hình thức:

LinkFormset = forms.modelformset_factory(Link) 
class LinkSectionForm(forms.ModelForm): 
    def __init__(self, **kwargs): 
     super(LinkSectionForm, self).__init__(**kwargs) 
     self.link_formset = LinkFormset(instance=self.instance, 
             data=self.data or None, 
             prefix=self.prefix) 

    def is_valid(self): 
     return (super(LinkSectionForm, self).is_valid() and 
        self.link_formset.is_valid()) 

    def save(self, commit=True): 
     # Supporting commit=False is another can of worms. No use dealing 
     # it before it's needed. (YAGNI) 
     assert commit == True 
     res = super(LinkSectionForm, self).save(commit=commit) 
     self.link_formset.save() 
     return res 

(Đó chỉ đến ra khỏi đỉnh đầu của tôi và không được kiểm tra, nhưng nó sẽ giúp bạn đi đúng hướng.)

Mẫu của bạn chỉ cần hiển thị biểu mẫu và form.link_formset một cách thích hợp.

+7

Chúng tôi có thể lấy mẫu mã mẫu cho câu trả lời này không? Có nên sử dụng fork_form.html của Django cho việc này không? Ngoài ra, trong Django 1.2.3, dòng đầu tiên nên được LinkFormSet = forms.inlineformset_factory (Link) – Bluu

+3

Hi tôi đang cố gắng để có được điều này để làm việc nhưng tôi nhận được lỗi với LinkFormset không muốn lấy dụ = self.instance, bất kỳ reccomendations – Hugoagogo

+1

Ý tưởng tuyệt vời để làm tổ trong formset. Sẽ kiểm tra rằng :-) – vdboor

1

Đề xuất của tôi thực sự là thay đổi mô hình của bạn. Tại sao không có ForeignKey trong Link đến LinkSection? Hoặc, nếu nó không phải OneToMany, có lẽ là một lĩnh vực ManyToMany? Giao diện quản trị sẽ tạo miễn phí. Tất nhiên, tôi không khuyên bạn nên điều này nếu liên kết không hợp lý có bất cứ điều gì để làm với các phần liên kết, nhưng có lẽ họ làm gì? Nếu không, vui lòng giải thích tổ chức dự định là gì. (Ví dụ: 3 liên kết cho mỗi phần được cố định hoặc tùy ý?)

+0

Ngớ ngẩn tôi, tôi đã sử dụng trường ForeignKey mà tôi muốn ở đó :). Các liên kết phải làm với các phần liên kết (dự định như là một tiêu đề của các loại). 3 liên kết trên mỗi phần là tùy ý. Tôi sẽ chỉnh sửa OP để phản ánh tốt hơn điều này. –

0

Bạn có thể tạo một lớp mới, tương tự như TabularInline hoặc StackedInline, có thể sử dụng chính trường nội tuyến.

Hoặc, bạn có thể tạo mẫu quản trị mới, cụ thể cho mẫu của bạn. Nhưng điều đó tất nhiên sẽ ghi đè các tính năng tiện lợi của giao diện quản trị.

4

Django-nested-inlines được xây dựng chỉ cho điều này. Cách sử dụng rất đơn giản.

from django.contrib import admin 
from nested_inlines.admin import NestedModelAdmin, NestedStackedInline, NestedTabularInline 
from models import A, B, C 

class MyNestedInline(NestedTabularInline): 
    model = C 

class MyInline(NestedStackedInline): 
    model = B 
    inlines = [MyNestedInline,] 

class MyAdmin(NestedModelAdmin): 
    pass 

admin.site.register(A, MyAdmin) 
Các vấn đề liên quan