3

これに対する答えが明らかである場合はお詫びします-私はdjango/pythonに非常に慣れていないため、これまでの検索で解決策を見つけることができませんでした。

私は簡単なクエリセットを持っています、例えば

members = LibraryMembers.objects.all()

これで私ができること:-

for m in members:
  member_books = LibraryBorrows.objects.filter(member_id=m[u'id'])

私が本当に欲しいのは、結果をjsonにシリアル化できるようにすることです。したがって、次のようになります:-

{
  "members":
  [
    {
      "id" : "1",
      "name" : "Joe Bloggs"
      "books":
      [
        {
          "name" : "Five Go Exploring",
          "author" : "Enid Blyton",
        },
        {
          "name" : "Princess of Mars",
          "author" : "Edgar Rice Burroughs",
        },
      ]
    }
  ]
}

私の考えでは、試してみるべき明らかなことは次のとおりでした:-

for m in members:
  m[u'books'] = LibraryBorrows.objects.filter(member_id=m[u'id'])

ただし、 TypeError: 'LibraryBorrows' オブジェクトは項目の割り当てをサポートしていません

私が求めているものを達成する方法はありますか?

4

2 に答える 2

1

モデル インスタンスは実際には辞書ではありません。モデル インスタンスの代わりに dict が必要な場合Queryset.values()は、友人です。必要なフィールドのみを含む dict のリストを取得し、データベースから不要なフィールドを取得して本格的なモデル インスタンスを構築するオーバーヘッドを回避できます。

>> members = LibraryMember.objects.values("id", "name")
>> print members
[{"id" : 1, "name" : "Joe Bloggs"},]

次に、コードは次のようになります。

members = LibraryMember.objects.values("id", "name")
for m in members: 
    m["books"] = LibraryBorrows.objects.filter(
      member_id=m['id']
      ).values("name", "author")

親行ごとに 1 つの追加の db クエリを発行する必要がありますが、LibraryMember の数によっては効率的ではない場合があります。数百以上の LibraryMember がある場合は、代わりに LibraryMember の関連フィールドを含めて LibraryBorrow でクエリを実行し、次に LibraryMember ID に基づいて行を再グループ化することをお勧めします。

from itertools import group_by

def filter_row(row):
    for name in ("librarymember__id", "librarymember__name"):
        del row[name]
    return row

members = []
rows = LibraryBorrow.objects.values(
    'name', 'author', 'librarymember__id', 'librarymember__name'
     ).order_by('librarymember__id')


for key, group in group_by(rows, lambda r: r['librarymember__id']):
    group = list(group)     
    member = {
      'id' : group[0]['librarymember_id'], 
      'name':group[0]['librarymember_name']
      'books' = [filter_row(row) for row in group] 
       }
    members.append(member)

NB : これは時期尚早の最適化と見なすことができます (データベースに LibraryMember が 2 つしかない場合はそうなるでしょう) が、1 つのクエリと少しの後処理で数百以上のクエリを交換すると、通常、「実際の生活」に大きな違いが生じます。データセット。

于 2012-07-07T13:27:54.350 に答える
1

WellmLibraryMemberオブジェクトなので、辞書として扱うことはできません。補足として: ほとんどの人はモデルに複数形の名前を付けません。これは、オブジェクトのコレクションではなく、オブジェクトをモデル化する単なるクラスであるためです。

考えられる解決策の 1 つは、両方のオブジェクトから必要な値を含む辞書のリストを作成することです。

o = [ { "id": m.id, "name": m.name, "books": [{"name": b.name, "author": b.author} for b in m.libraryborrows_set.all()] } for m in LibraryMembers.objects.all()]

関連マネージャーを使用して、特定のメンバーのブックを取得できることに注意してください。より明確にするために:

o = []
for m in LibraryMembers.objects.all():
   member_books = [{"name": b.name, "author": b.author} for b in m.libraryborrows_set.all()] 
   o.append( { "id": m.id, "name": m.name, "books": member_books } )  

編集

すべてのフィールドをシリアル化するには:

members = []
for member in LibraryMembers.objects.all():
    member_details = {}
    for field in member._meta.get_all_field_names():
        member_details[field] = getattr(member, field)
    books = []
    for book in member.librayborrows_set.all():
        book_details = {}
        for field in book._meta.get_all_field_names():
            book_details[field] = getattr(book, field)
        books.append(book_details)
    member_details['books'] = books
    members.append(member_details)

今日まで聞いたことのない DjangoFullSerializers も見つけました。

http://code.google.com/p/wadofstuff/wiki/DjangoFullSerializers

于 2012-07-07T11:49:07.200 に答える