ジャンゴ:任意の数の名前のない urls.py パラメータ
-
05-07-2019 - |
質問
多数のフィールドと 20000 以上のテーブル行を持つ Django モデルがあります。人間が判読できる URL と、大きなリストを任意のサブリストに分割する機能を容易にするために、次のような URL が必要です。
/browse/<name1>/<value1>/<name2>/<value2>/ .... etc ....
ここで、「name」はモデル属性にマップされ、「value」はその属性の検索基準です。各「名前」はカテゴリのように扱われ、カテゴリが一致するモデル インスタンスのサブセットが返されます。
これは GET パラメータで処理できますが、ユーザーと検索エンジンの両方のために、より読みやすい URL の方が望ましいと考えています。これらの URL サブセットは、このモデルを表示する各ページに埋め込まれるため、見栄えの良い URL を作成する努力は価値があると思われます。
理想的には、各名前と値のペアは、という名前のパラメーターとしてビュー関数に渡されます。 name1
, name2
, 、など。ただし、正規表現の一致するテキストを介して名前付きパターンを定義することは可能だとは思いません。そこは間違っているでしょうか?
したがって、次のようなことを行う必要があるようです:
urlpatterns = patterns('',
url(r'^browse/(?:([\w]+)/([\w]+)/)+$', 'app.views.view', name="model_browse"),
)
これは、2 つの名前と値のペアの任意のセットに一致するはずです。正常に一致しても、姓と値のペアがパラメーターとしてビュー関数に渡されるだけです。私の推測では、各一致が前の一致を上書きしているのではないかと思います。(?:...)+ を含むことが原因であると推測して、代わりに単純な繰り返しパターンを試してみました。
urlpatterns = patterns('',
url(r'^browse/([\w]+/)+$', 'app.views.view', name="model_browse"),
)
...同じ問題が発生しましたが、今回は *args
最後に一致したパターンのみが含まれます。
これは Django の URL ディスパッチャや Python の正規表現サポートの制限ですか?これらの方法のいずれかが機能するはずです。URL 内の考えられる各モデル属性をオプションの (.*) パターンとしてハードコーディングせずにこれを実現する方法はありますか?
解決
考えられる可能性は、URLパターン部分内の可能な値の文字列全体に一致し、ビュー内の特定の部分を引き出すことです。例として:
urlpatterns = patterns('',
url(r'^browse/(?P<match>.+)/$', 'app.views.view', name='model_browse'),
)
def view(request, match):
pieces = match.split('/')
# even indexed pieces are the names, odd are values
...
使用した正規表現についての約束はありませんが、私が言っていることは理解できたと思います。
(正規表現を修正しようとするために編集されました。)
他のヒント
Adamには同意しますが、urls.pyのパターンは次のようにすべきだと思います:
... r'^browse/(?P<match>.+)/$' ...
「\ w」は「単語」文字のみに一致しますが、「。」何にでもマッチします。
質問を読んでいる間、同じ答えが返ってきました。
model_browseビューは、クエリパラメーターを並べ替えて汎用ルーターとして使用するための最良の方法だと思います。
Adamの答えは私のソリューションよりも一般的だと思いますが、URLで固定数の引数を使用したい場合は、次のようなこともできます。
次の例は、store
とyear
、month
およびday
の名前を入力して、ある場所の1日のすべての売上を取得する方法を示しています。
urls.py :
urlpatterns = patterns('',
url(r'^baseurl/location/(?P<store>.+)/sales/(?P<year>[0-9][0-9][0-9][0-9])-(?P<month>[0-9][0-9])-(?P<day>[0-9][0-9])/$', views.DailySalesAtLocationListAPIView.as_view(), name='daily-sales-at-location'),
)
また、(?P<store>.+)
を(?P<store>[0-9]+)
に変更して、ストアのIDを使用することもできます。 location
とsales
はキーワードではなく、URLの読みやすさを向上させるだけです。
views.py
class DailySalesAtLocationListAPIView(generics.ListAPIView):
def get(self, request, store, year, month, day):
# here you can start using the values from the url
print store
print year
print month
print date
# now start filtering your model
誰にでも役立つことを願っています!
よろしく、
マイケル
私は別の解決策を持っています。これは前のものとあまり変わりませんが、より洗練されています。
url(r'^my_app/(((list\/)((\w{1,})\/(\w{1,})\/(\w{1,3})\/){1,10})+)$'
使ったことがある 名前のない URL パラメータ そして反復的な正規表現。「を取得しない」は有効な正規表現ではありません:複数の繰り返し」リストの先頭に単語を置きます。
私はまだリストを受信するビューで作業しています。でも、args や kwargs を経由するのは間違っていると思います。まだ正確に言うことはできません。
私の2セント