web-dev-qa-db-ja.com

DRY URL in Django JavaScript

Django= Appengineで使用しています。Django reverse()関数をすべての場所で使用し、すべてをDRY可能な限り。

しかし、これをクライアント側のJavaScriptに適用するのに問題があります。渡されたIDに応じて一部のデータをロードするJSクラスがあります。このデータの取得元のURLをハードコーディングしない標準的な方法はありますか?

var rq = new Request.HTML({
    'update':this.element,
}).get('/template/'+template_id+'/preview'); //The part that bothers me.
50
noio

最も合理的な解決策は、JavaScriptファイルでURLのリストを渡し、クライアントでリバース()に相当するJavaScriptを使用できるようにすることです。唯一の問題は、URL構造全体が公開されていることです。

これがそのような function です(これから question )。

8
noio

別の方法があります。これは、URL構造全体を公開する必要がないか、各URLを解決するためのAjaxリクエストを必要としません。それは本当に美しくはありませんが、シンプルさで他の人を打ち負かしています:

var url = '{% url blog_view_post 999 %}'.replace (999, post_id);

(もちろん、blog_view_postのURLには、マジック999自体を含めることはできません。)

32
Anatoly Rr

私はこれに苦労したばかりで、少し異なる解決策を思いつきました。

私の場合、外部のJSスクリプトでAJAX呼び出しをボタンのクリックで呼び出します(他の処理を行った後))。

HTMLでは、HTML-5カスタム属性を使用しました。

_<button ... id="test-button" data-ajax-target="{% url 'named-url' %}">
_

次に、JavaScriptで、単にしました

_$.post($("#test-button").attr("data-ajax-target"), ... );
_

つまり、Djangoのテンプレートシステムがすべてのreverse()ロジックを実行してくれました。

9
kdopen

JavaScriptからDjangoへのすべてのパラメーターがrequest.GETまたはrequest.POSTとして渡されると想定します。Nice形式のURLは必要ないため、ほとんどの場合これを行うことができます。 JavaScriptクエリ用。

それから唯一の問題は、URLをDjangoからJavaScriptに渡すことです。そのためのライブラリを公開しました。コード例:

rls.py

def javascript_settings():
    return {
        'template_preview_url': reverse('template-preview'),
    }

javascript

$.ajax({
  type: 'POST',
  url: configuration['my_rendering_app']['template_preview_url'],
  data: { template: 'foo.html' },
});
4
Tomasz Wysocki

アナトリーの回答に似ていますが、もう少し柔軟です。ページの上部に配置:

<script type="text/javascript">
window.myviewURL = '{% url myview foobar %}';
</script>

次に、次のようなことができます

url = window.myviewURL.replace('foobar','my_id');

または何でも。 URLに複数の変数が含まれている場合は、replaceメソッドを複数回実行するだけです。

4
Hilton Shumway

アナトリーのアイデアは好きですが、特定の整数を使用するのは危険だと思います。通常、オブジェクトIDを指定する必要があります。これは常に正である必要があるため、プレースホルダーとして負の整数を使用します。つまり、次のように-?をURL定義に追加します。

url(r'^events/(?P<event_id>-?\d+)/$', events.views.event_details),

次に、次のように記述することで、テンプレートの逆URLを取得できます

{% url 'events.views.event_details' event_id=-1 %}

そして、JavaScriptでreplaceを使用して、プレースホルダー-1を置き換え、テンプレートで次のように記述します。

<script type="text/javascript">
var actual_event_id = 123;
var url = "{% url 'events.views.event_details' event_id=-1 %}".replace('-1', actual_event_id);
</script>

これは複数の引数にも簡単に拡張でき、特定の引数のマッピングはテンプレートに直接表示されます。

2
leifdenby

私はこれのための簡単なトリックを見つけました。あなたのURLが次のようなパターンである場合:

_"xyz/(?P<stuff>.*)$"
_

そして、あなたは実際にものを提供せずにJSでリバースしたい(これを提供するためにJSランタイムに延期する)-あなたは以下を行うことができます:

ビューを変更してパラメーターにデフォルト値(なし)を設定し、設定されていない場合はエラーで応答して処理します。

views.py

_def xzy(stuff=None):
  if not stuff:
    raise Http404
  ... < rest of the view code> ...
_
  • URLの一致を変更して、パラメーターをオプションにします:"xyz/(?P<stuff>.*)?$"
  • そしてテンプレートjs​​コードで:

    .ajax({url: "{{url views.xyz}}" + js_stuff、... ...})

生成されたテンプレートには、JS内のパラメーターなしのURLが含まれているはずです。JSでは、パラメーター上で単純に連結できます。

1
Danny Staple

私が付いてきたソリューションの1つは、バックエンドでURLを生成し、それらを何らかの方法でブラウザーに渡すことです。

すべての場合に適しているわけではありませんが、(AJAXが入力された)テーブルがあり、行をクリックすると、このテーブルの1つのエントリにユーザーが移動するはずです。

(私は Django-restframeworkDatatables を使用しています)。

AJAXの各エントリには、URLが添付されています。

class MyObjectSerializer(serializers.ModelSerializer):
    url = SerializerMethodField()
    # other elements

    def get_url(self, obj):
       return reverse("get_my_object", args=(obj.id,))

ajaxをロードすると、各URLがデータ属性として行に添付されます。

var table = $('#my-table').DataTable({
   createdRow: function ( row, data, index ) {
      $(row).data("url", data["url"])
   }
});

クリックすると、このデータ属性をurlに使用します。

table.on( 'click', 'tbody tr', function () {
  window.location.href = $(this).data("url");
} );
0
Pax0r

このパッケージを使用: https://github.com/ierror/Django-js-reverse

JSには、Djangoで定義されたすべてのURLを持つオブジェクトがあります。それは私が今までに見つけた最良のアプローチです。

あなたがする必要があるのは、ベーステンプレートのヘッドに生成されたjsを追加し、URLを追加するたびに生成されたjsを更新する管理コマンドを実行することです。

0
Karim N Gorjux