http://example.com/depict?smiles=CO&width=200&height=2 (および他のいくつかのオプションの引数)のようなURLがあります。
私のurls.pyには以下が含まれます:
urlpatterns = patterns('',
(r'^$', 'cansmi.index'),
(r'^cansmi$', 'cansmi.cansmi'),
url(r'^depict$', cyclops.Django.depict, name="cyclops-depict"),
そのURLにアクセスして、作成された200x200のPNGを取得できるので、その部分が機能することがわかります。
"cansmi.cansmi"応答のテンプレートで、クエリパラメータを指定して、名前付きテンプレート "cyclops-depict"のURLを作成します。できると思った
{%url cyclops-depict smiles = input_smiles width = 200 height = 200%}
ここで、「input_smiles」は、フォーム送信を介したテンプレートへの入力です。この場合、それは文字列 "CO"であり、上にあるようなURLを作成すると思いました。
このテンプレートは、TemplateSyntaxErrorで失敗します。
レンダリング中に例外をキャッチ:引数 '()'とキーワード引数 '{' smiles ':u'CO'、 'height':200、 'width':200} 'が指定された' cyclops-depict 'の逆が見つかりません。
これは、StackOverflowと他の場所の両方で、かなり一般的なエラーメッセージです。私が見つけたすべてのケースで、人々はそれらをURLパス正規表現のパラメーターで使用していましたが、パラメーターがクエリに入る場所ではそうではありません。
それは私がそれを間違っていることを意味します。どうすれば正しくできますか?つまり、テンプレートの何かを使用して、パスとクエリパラメータを含む完全なURLを構築したいと考えています。
参考のため、
% python manage.py Shell
Python 2.6.1 (r261:67515, Feb 11 2010, 00:51:29)
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from Django.core.urlresolvers import reverse
>>> reverse("cyclops-depict", kwargs=dict())
'/depict'
>>> reverse("cyclops-depict", kwargs=dict(smiles="CO"))
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/Library/Python/2.6/site-packages/Django/core/urlresolvers.py", line 356, in reverse
*args, **kwargs)))
File "/Library/Python/2.6/site-packages/Django/core/urlresolvers.py", line 302, in reverse
"arguments '%s' not found." % (lookup_view_s, args, kwargs))
NoReverseMatch: Reverse for 'cyclops-depict' with arguments '()' and keyword arguments '{'smiles': 'CO'}' not found.
通常の式にはプレースホルダーがありません(そのため、NoReverseMatchを取得しています)。
url(r'^depict$', cyclops.Django.depict, name="cyclops-depict"),
あなたはこのようにすることができます:
{% url cyclops-depict %}?smiles=CO&width=200&height=200
RLconf検索にはGETまたはPOSTパラメータ は含まれません
または、{%url%}タグを使用する場合は、URLパターンを次のように再構築する必要があります
r'^depict/(?P<width>\d+)/(?P<height>\d+)/(?P<smiles>\w+)$'
その後、あなたは次のようなことができます
{% url cyclops-depict 200 200 "CO" %}
フォローアップ:
カスタムタグの簡単な例:
from Django.core.urlresolvers import reverse
from Django import template
register = template.Library()
@register.tag(name="myurl")
def myurl(parser, token):
tokens = token.split_contents()
return MyUrlNode(tokens[1:])
class MyUrlNode(template.Node):
def __init__(self, tokens):
self.tokens = tokens
def render(self, context):
url = reverse('cyclops-depict')
qs = '&'.join([t for t in self.tokens])
return '?'.join((url,qs))
このタグをテンプレートで次のように使用できます。
{% myurl width=200 height=200 name=SomeName %}
うまくいけば、それは次のようなものを出力するはずです
/depict?width=200&height=200&name=SomeName
いくつかの回答で提案されているように、文字列連結によるクエリ文字列を使用してURLを構築することは、文字列連結によってSQLクエリを構築するのと同じくらい悪い考えです。ユーザーが入力した(信頼できない)入力を使用すると、複雑で見苦しく、特に危険です。残念ながらDjangoは、クエリパラメータを reverse 関数に渡す簡単な可能性を提供しません。
Python標準 rllib は、必要なクエリ文字列エンコーディング機能を提供します。
私のアプリケーションでは、ヘルパー関数を作成しました:
def url_with_querystring(path, **kwargs):
return path + '?' + urllib.urlencode(kwargs) # for Python 3, use urllib.parse.urlencode instead
次に、ビューで次のように呼び出します。
quick_add_order_url = url_with_querystring(reverse(order_add),
responsible=employee.id, scheduled_for=datetime.date.today(),
subject='hello world!')
# http://localhost/myapp/order/add/?responsible=5&
# scheduled_for=2011-03-17&subject=hello+world%21
スペースや感嘆符などの特殊文字の適切なエンコードに注意してください!
組み込みのDjangoの QueryDict を使用することをお勧めします。また、リストを適切に処理します。 Endは、いくつかの特殊文字(=
、?
、/
、 '#'など)を自動的にエスケープします。
from Django.http import QueryDict
from Django.core.urlresolvers import reverse
q = QueryDict('', mutable=True)
q['some_key'] = 'some_value'
q.setlist('some_list', [1,2,3])
'%s?%s' % (reverse('some_view_name'), q.urlencode())
# '/some_url/?some_list=1&some_list=2&some_list=3&some_key=some_value'
q.appendlist('some_list', 4)
q['value_with_special_chars'] = 'hello=w#rld?'
'%s?%s' % (reverse('some_view_name'), q.urlencode())
# '/some_url/?value_with_special_chars=hello%3Dw%23rld%3F&some_list=1&some_list=2&some_list=3&some_list=4&some_key=some_value'
テンプレートでこれを使用するには、カスタムテンプレートタグを作成する必要があります
元の回答はどちらも、ビューコード内のURLを解決する関連する問題に対処していません。今後の検索で、これを行う場合は、次のようなkwargsを使用します。
reverse('myviewname', kwargs={'pk': value})
Urllibを使用した答えは確かに良いですが、文字列の連結を回避しようとしていたときに、path + '?' + urllib.urlencode(kwargs)
で使用しました。 path
にクエリパルマがすでにある場合、問題が発生する可能性があります。
変更された関数は次のようになります。
def url_with_querystring(url, **kwargs):
url_parts = list(urlparse.urlparse(url))
query = dict(urlparse.parse_qsl(url_parts[4]))
query.update(kwargs)
url_parts[4] = urllib.urlencode(query)
return urlparse.urlunparse(url_parts)
以前の回答の作業上のバリエーションと、これに関する私の経験。
from Django.urls import reverse
from Django.utils.http import urlencode
def build_url(*args, **kwargs):
params = kwargs.pop('params', {})
url = reverse(*args, **kwargs)
if params:
url += '?' + urlencode(params)
return url
使い方:
>>> build_url('products-detail', kwargs={'pk': 1}, params={'category_id': 2})
'/api/v1/shop/products/1/?category_id=2'