2010-07-30 30 views
39

Từ các tài liệu Django ...Làm cách nào để truy cập các thuộc tính của bảng "qua" nhiều từ một mẫu django?

Khi bạn chỉ đơn giản đối phó với nhiều-nhiều mối quan hệ như trộn và kết hợp pizza và toppings, một ManyToManyField giữa các ý kiến ​​tất cả các bạn cần. Tuy nhiên, đôi khi bạn có thể cần phải kết hợp dữ liệu với mối quan hệ giữa hai mô hình.

Ví dụ: hãy xem xét trường hợp của ứng dụng theo dõi các nhóm nhạc mà nhạc sĩ thuộc về. Có một mối quan hệ nhiều-nhiều giữa một người và các nhóm mà họ là một thành viên, vì vậy bạn có thể sử dụng một ManyToManyField để đại diện cho mối quan hệ này. Tuy nhiên, có rất nhiều chi tiết về tư cách thành viên mà bạn có thể muốn thu thập, chẳng hạn như ngày mà người đó tham gia nhóm.

Đối với những tình huống này, Django cho phép bạn chỉ định mô hình sẽ được sử dụng để điều chỉnh mối quan hệ nhiều-nhiều. Sau đó, bạn có thể đặt các trường bổ sung trên mô hình trung gian. Mô hình trung gian được liên kết với ManyToManyField bằng cách sử dụng đối số thông qua để trỏ đến mô hình sẽ hoạt động như một trung gian. Ví dụ nhạc sĩ của chúng tôi, đoạn code sẽ giống như thế này:

class Person(models.Model): 
    name = models.CharField(max_length=128) 

    def __unicode__(self): 
     return self.name 

class Group(models.Model): 
    name = models.CharField(max_length=128) 
    members = models.ManyToManyField(Person, through='Membership') 

    def __unicode__(self): 
     return self.name 

class Membership(models.Model): 
    person = models.ForeignKey(Person) 
    group = models.ForeignKey(Group) 
    date_joined = models.DateField() 
    invite_reason = models.CharField(max_length=64) 

Bây giờ bạn đã thiết lập ManyToManyField của bạn để sử dụng mô hình trung gian của bạn (thành viên, trong trường hợp này), bạn đã sẵn sàng bắt đầu tạo một số mối quan hệ nhiều-nhiều. Bạn làm điều này bằng cách tạo ra các trường hợp của mô hình trung gian:

ringo = Person.objects.create(name="Ringo Starr") 
paul = Person.objects.create(name="Paul McCartney") 
beatles = Group.objects.create(name="The Beatles") 

m1 = Membership(person=ringo, group=beatles, 
...  date_joined=date(1962, 8, 16), 
...  invite_reason= "Needed a new drummer.") 

m1.save() 

beatles.members.all() 
[<Person: Ringo Starr>] 

ringo.group_set.all() 
[<Group: The Beatles>] 

m2 = Membership.objects.create(person=paul, group=beatles, 
...  date_joined=date(1960, 8, 1), 
...  invite_reason= "Wanted to form a band.") 

beatles.members.all() 
[<Person: Ringo Starr>, <Person: Paul McCartney>] 

nguồn: http://docs.djangoproject.com/en/dev/topics/db/models/#intermediary-manytomany

Câu hỏi của tôi là, làm thế nào để tôi thiết lập xem và mẫu của tôi để truy cập vào các thuộc tính bổ sung. Giả sử tôi có một trang band và tôi muốn hiển thị tên ban nhạc, lặp lại thông qua các hồ sơ thành viên và tên hiển thị và date_joined.

Tôi có nên chuyển đối tượng ban nhạc cho mẫu không? Hay tôi vượt qua các đối tượng thành viên bằng cách nào đó?

Và làm cách nào để tạo vòng lặp trong mẫu?

Cảm ơn.

+1

tôi sẽ xem xét rút ngắn trích từ tài liệu django một chút. Những người có khả năng đáp ứng có thể đã quen thuộc với họ và sẽ dễ dàng hơn để nhận ra câu hỏi thực tế theo cách đó. – cji

Trả lời

32

Cách dễ nhất là chỉ để chuyển ban nhạc đến mẫu. Các mẫu có khả năng điều hướng các mối quan hệ giữa các mô hình và có cả các thành viên và các trình quản lý truy vấn member_set trên Group.Vì vậy, đây là cách tôi sẽ làm điều đó:

xem:

def group_details(request, group_id): 
    group = get_object_or_404(Group, pk=group_id) 
    return render_to_response('group_details.html', 
           {'group': group}) 

mẫu:

<h2>{{ group.name }}</h2> 
{% for membership in group.membership_set.all %} 
    <h3>{{ membership.person }}</h3> 
    {{ membership.date_joined }} 
{% endfor %} 
+2

Điều đó hoạt động hoàn hảo. Tôi đã cố gắng lặp qua group.membership.all. Tôi cần phải đọc lên trên _set. Cảm ơn! – Alex

+0

Nhưng nếu bạn cần một cái gì đó phức tạp hơn, tức là đặt hàng, thực hành tiêu chuẩn lọc vv là làm điều đó trong khung nhìn và sau đó vượt qua nó trong ngữ cảnh? – CpILL

+0

Một điểm quan trọng là tên lớp trong trường hợp thấp hơn của bảng thông qua được sử dụng "thành viên" ,. – MagicLAMP

6

Tôi không chắc đó có phải là giải pháp hay không, nhưng việc truyền các đối tượng quan hệ vào mẫu chắc chắn hoạt động. Theo quan điểm của bạn, nhận QuerySet của các đối tượng thành viên:

rel = Membership.objects.filter(group = your_group).select_related() 

và vượt qua nó để mẫu, nơi bạn có thể lặp trên nó với {% for %}

{% for r in rel %} 
    {{ r.person.name }} joined group {{ r.group.name }} on {{ r.date_joined }}<br /> 
{% endfor %} 

Lưu ý rằng điều này không nên thực hiện bất cứ thắc mắc thêm vì select_related() .

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