31

アイテムのリストを表示し、ユーザーがフォームに入力してアイテムに追加できるDjangoページがあるとします(アイテムの投稿と呼びましょう)。

欲しいもの:このページのURLはビューを参照しています。ビューは他の2つのビュー(ここでは「サブビュー」と呼びます)を呼び出し、各サブビューはそのセクションをレンダリングして結果を返します。次に、メインビューはサブビューの結果を結合し、それを返します。

理想的には、ページでJavaScriptを簡単にチェックします。JavaScriptが有効になっている場合、フォームの送信ボタンは、フォームの追加を処理するサブビューに「Ajax」され、ページはそのように更新されます。 。後で投稿のリストを更新するリクエストをトリガーすることもできると思います。

では、メインビューの2つのサブビューを連結するにはどうすればよいですか?これは可能ですか?

更新:「サブビュー」は私が作った用語です。私が欲しいのは、Ajaxが直接呼び出して意味のあるものを返すか、別のビュー(これを「メインビュー」と呼びます)から呼び出すことができるビューです。この「メインビュー」によって呼び出された場合、メインビューは複数の「サブビュー」からのデータの返送をどのように処理しますか?

これを行う簡単な方法はありますか?これは、ページ内の複数のビューについて考えるのに適切な方法ですか?責任の分離を気にする必要がありますか?

4

3 に答える 3

20

django のビューは、最終的に Response オブジェクトを返す任意の呼び出し可能オブジェクトです。そのビュー内で、自分に合った組織に作業を分割できます。たぶん、あなたのビューは 100% 他のメソッドに委任されます。

あなたの場合、メイン ビューはデータに対して 2 つの他の関数を呼び出します。Request オブジェクトも受け入れてそれを利用する場合、これらはビューになることもあります。また、django ビューと見なされるには、Response オブジェクトを返す必要があります。これは、URL を指定する方法だからです。しかし、Response オブジェクトを返す他の 2 つのビューを用意しても、実際には何の役にも立ちません。おそらく必要なのは、特定のタスクを実行してデータ構造を返す他のメソッド、またはテンプレートのレンダリングされたスニペットでさえあります。次に、これらのデータを使用するか、テンプレート文字列を一緒にマージして、それをメインの応答で返します。

Response オブジェクトを返す他のビューを実際に使用する場合は、それらから本文を取得し、それらを独自の応答にマージするなどの操作を行うことができます:
https://docs.djangoproject.com/en/1.4 /ref/リクエスト-レスポンス/

実際、チュートリアルと大差ありません。データに対して他のメソッドを呼び出しているだけです。整理したい場合は、データ処理ロジックをビュー関数から分離する必要があります。メイン ビューは、値に対してこれらのデータ処理関数を呼び出します。そして、「サブビュー」は、これらの個々のデータ関数も呼び出して応答にラップする単純なビューになります。

擬似:

def mainView(request):
    val = data1()
    val2 = data2()
    response = # val + va2 + other stuff
    return response

def subView1(request):
    val = data1()
    response = # val  + stuff
    return response 

def subView2(request):
    val2 = data2()
    response = # val2  + stuff
    return response 

def data1():
    val = # get data
    return val 

def data2():
    val2 = # get data
    return val2
于 2012-05-15T20:26:46.890 に答える
19

ビューには、ビュー関連のロジックのみを含める必要があります。

  • ビューは、リクエストを処理し、リクエストされたデータを提供するためのものです
  • これには、ユーザーの承認/許可の確認と、指定されたパラメーターの処理が含まれます
  • 要求されたデータを取得するのが簡単でない場合は、コードをより適切な場所 (モデルまたはフォームの定義、または別のカスタム プレース) に外部委託します。

計算を外部委託して再利用可能にし、ビューからこれらのメソッドを呼び出してサイズを小さく保ちます。

それにもかかわらず、他の何か、つまり と を含むテンプレートが必要になる場合がextendsありincludeます。

HTML コードのベース レイアウトを作成し、extends別の場所でレンダリングできる特定のブロックを定義できます。例?Ok。

base.html:

<!doctype html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>{% block title %}My Site{% endblock %}</title>
    </head>
    <body>
        <div id="header">
            <h1>My Site</h1>
        </div>
        {% block content %}{% endblock %}
    </body>
</html>

次に、他のテンプレートで、基本テンプレートで定義したブロックtitleを上書きできます。content

{% extends "base.html" %}

{% block title %}My Page{% endblock %}

{% block content %}
<h2>My Page</h2>
<div>lorem ipsum</div>
{% endblock %}

また、次のようなサブテンプレートを作成できます。名前を付けましょう_item.html

<li class="item">
  <span>{{ something.foo }}</span>
  <strong>{{ something.bar }}</span>
</li>

そのスニペットを他のテンプレートに含めて、任意の数のパラメーターを渡すことができます。

{% for something in mymodel.mym2mrelation.all %}
    {% include "_item.html" with something=something only %}
{% endfor %}

当然、両方の概念を組み合わせることができます。そのようです:

{% extends "base.html" %}

{% block title %}My Page{% endblock %}

{% block content %}
<h2>My Page</h2>
<div>lorem ipsum</div>
<ul>
{% for something in mymodel.mym2mrelation.all %}
    {% include "_item.html" with something=something only %}
{% endfor %}
</ul>
{% endblock %}

それが役立つことを願っています。

于 2012-05-15T20:43:42.857 に答える
10

これは、クラス ベースのビューを導入する絶好の機会です。

クラスメソッドは本質的に、ロジックを再利用可能なスニペットに分割する「サブビュー」です。

分割関数の可読性が必要な場合は、django のクラス ベースのビューを使用することによってのみ改善されます (デフォルトで提供されるすべての機能と、クラス インスタンスを介した要求、kwargs、args などへのアクセスを介して)。

ドキュメントには、リクエスト パラメータに基づいて JSON レスポンスまたは HTML レスポンスを返す良い例も含まれています (まさにこの状況です)。

一番良いところ?クラスベースのビューを将来のビューでミックスインとして再利用できます。ドキュメントの例を見て、クラス ベースのビューを変換して、単純なサブクラスを介してテンプレート コンテキストの JSON 応答を処理する方法を確認してください。

于 2012-05-15T20:48:43.383 に答える