Django M:Nフィールドorder byの使用(コメント、Subquery、OuterRefの使用)


入社8カ月目の青少年先端開発者の仕事日記と記録だ.
内容が間違っていたり、もっと良い方法があることがわかったらコメントに書いてください
本当に役に立ちます.前もってありがとうございました!🙏
n/a.結論
情報
本明細書では、order_byを使用して、モデルのクエリー・セットを特定のフィールドに従ってソートします.
ただし、ソートするモデルとM:N関係を確立するモデルの複数のフィールドを基準とすると、ソート後に重複するデータが発生する可能性があります.
(M:Nのため)複数のオブジェクトと同時に接続されている場合、どのオブジェクトに基づいてソートするかは判断できません.したがって、各オブジェクトに対してすべてのデータが作成され、ソートされます.
この問題を解決するために、Subqueryを使用してm 2 mリレーションシップモデルに必要なオブジェクト情報のみを含むアノテーションフィールドを作成し、最終的にこの値を基準にorder_byメソッドを実行し、重複データの消去に成功しました.
に感銘を与える
いろいろな方法を考え続けましょう.問題の原因は最初に想定した原因の中にあるかもしれないと断定し、結果的に問題を解決する時間が長くなった.
  • スタックオーバーフローは正解ではありません.アイデアのみを取得し、ドキュメントまたは他の方法で私が得たアイデアが正しいかどうかを検証します.いつも時間が足りないので大変かもしれませんが、スタックオーバーフローやグーグル検索で得た知識が事実だと警戒すべきだと思います.
  • 後続アクション
    勉強が終わったら整理してリンクするつもりです.
    1.countとlenの違いを理解します.フロントでクエリーセットのcountをクリックしたときとforループしたときの実際のクエリーセットのオブジェクト数は異なり、ドアの後ろでcountをクリックすると、値を変えるところが最も混乱している部分です.countは実際のデータをロードしていないのではなく、ループで実際にクエリーを実行してキャッシュ・プロシージャを逃して混乱している可能性があります.この部分をもう一度細かく勉強する.
    経験と問題解決の過程をもっと詳しく書きたいです.
    開発の過程で,医師モデルのクエリーセットをソートする必要があることが起こった.
    ソート基準は、擬似モデルとM:N関係とを組み合わせたSpecialtyモデルのnameフィールドである.
    長い時間が経ってから知りましたが、数時間で連続して行われるシャベルの始まりは、あまり苦にならずに書かれた次のソートコードです.sorted_doctors = doctors.order_by('specialties', 'name')その後、フロントワークが行われ、一部のデータには重複データが含まれているため、実際のデータよりも多くのデータが表示されます.
    怪しいところが二つあります.
    1.病院の医師データの設定が間違っている.
    2.フロントエンドコードのどこかのエラーロジックなどでデータをコピーしています.
    病院の医師データの設定が間違っている.
    当初は病院の医師データの設定が間違っていたと考えられていた.しかし、それは私の願いにすぎない.Adminで確認したところ、データ設定に問題がないことがすぐに分かりました.
    他の可能性は考えられず、2つの疑いのうちの1つが原因だと判断したので、その後、2つ目の疑いが原因だと確定しました...
    フロントエンドコードのどこかの論理エラーなどで、データをコピーしています.
    次に、フロントにうっかりデータをコピーしてしまうところがあるのではないかと疑ったので、半日ひっくり返しました.
    原因がわからず、逆に不思議なことに、.countをデータに印刷すると、正常なデータの数が出てきます.
    すなわち,forループを実データ個数+重複データ個数に変換すれば,データの個数に問題はない.
    まったくあいまいな問題だ.また、ドラムや(特に)ドラムテンプレートに慣れていないので、何か知らないことが働いていると思いますので、データが増えて、グーグルやドラム毒を検索して、解決策を探しています.
    しばらく考えてから、ソートコードを再確認したところ、ソートされたデータでもクエリーセットの重複データのインデックスが異なることがわかりました.それから私はグーグルを始めて、私と同じ問題に直面した文章と問題の原因を発見しました.


    (ソースhttps://stackoverflow.com/questions/23600299/order-by-on-many-to-many-field-results-in-duplicate-entries-in-queryset)
    そしてデミンを通じてデータを再確認し、原因が明らかになった.重複データを生成する医師の対象には,2つの関連専門がある.
    あれから必ずやるから、毒蛇の捜査を始めた.
    1.最初にコメントで重複しないフィールドを作成し、これらの値に基づいてソートします.doctors.(first_specialty="").order_by('first_specialty')2.次に、first_specialtyに値を作成する必要があります.接続されているSpecialtyオブジェクトの数にかかわらず、私の条件を満たすオブジェクトの名前を入力すればいいです.
    調べてみましたが、ドラムのSubqueryメソッドを使うことで、クエリーセットで再度クエリーを行うことができ、注釈とともによく使われています.
    これに関連する良い例はdogsに記録される.
    from django.db.models import OuterRef, Subquery
    newest = Comment.objects.filter(post=OuterRef('pk')).order_by('-created_at')
    Post.objects.annotate(newest_commenter_email=Subquery(newest.values('email')[:1]))
    私のコードはこのように修正されました.
    doctors.annotate(
    	first_specialty = Subquery(
        	Specialty.objects.filter(doctors__id=OuterRef('id')).values('name')[:1]
    	)
    ).order_by('first_specialty')
    ここで、OuterQueryではSubquery外部クエリのフィールドを参照できます.すなわち、上記のコードは、OuterRef(「id」)を介して擬似オブジェクトのid値を参照することを可能にする.作成したサブクエリにより、first specificフィールドに最初のプロフェッショナルオブジェクトの名前を格納し、その値に基づいてソートして重複するデータを除去できます.
    ソース
    スタックオーバーフローの問題
    Django docs