TypeError: Đối tượng 'RelatedManager' không thể lặp lại


85

Django

Tôi có các mô hình tiếp theo:

class Group(models.Model):
    name = models.CharField(max_length=100)
    parent_group = models.ManyToManyField("self", blank=True)

    def __unicode__(self):
        return self.name


class Block(models.Model):

    name = models.CharField(max_length=100)
    app = models.CharField(max_length=100)
    group = models.ForeignKey(Group)

    def __unicode__(self):
        return self.name

giả sử, khối b1 có nhóm g1 . Bằng tên của nó, tôi muốn lấy tất cả các khối từ nhóm g1 . Tôi đã viết hàm đệ quy tiếp theo:

def get_blocks(group):

    def get_needed_blocks(group):
        for block in group.block_set:
            blocks.append(block)

        if group.parent_group is not None:
            get_needed_blocks(group.parent_group)

    blocks = []
    get_needed_blocks(group)
    return blocks

nhưng b1.group.block_set trả về cho tôi đối tượng RelatedManager , đối tượng này không thể lặp lại.

Để làm gì? Chuyện gì vậy?

Câu trả lời:


175

Thử đi:

block in group.block_set.all()

9
Có ai biết tại sao RelatedManager không được tạo ra để có thể lặp lại không? Tôi đã mong đợi mọi chuyện sẽ diễn ra theo cách đó ...
steepretzel.

2
Nhận xét này hơi muộn, nhưng lý do là bạn có thể sử dụng các phương pháp lọc trên trình quản lý để hạn chế truy vấn trước khi thực hiện tìm nạp vào db.
trứng

8
@stalepretzel, vì nó hoạt động chính xác như một trình quản lý django tiêu chuẩn. Bạn không gọi Model.objects và lặp lại nó. Bạn gọi Model.objects.all () và sau đó bạn lặp lại. Người quản lý Django = / = Bộ truy vấn Django.
Saturnix

và nếu bạn đang sử dụng nó trong vòng lặp mẫu cho, bạn có thể thực hiện {% for object in objects.other_object_set.all%}
Bruce

@stalepretzel ... đặc biệt là vì nó được gọi là "blocks_SET" - và không phải là "blocks_initymanager". Hoặc "blocks_set_osystemmanager".
Klaws

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.