200

私は次のようなDjangoURLを持っています:

url(
    r'^project_config/(?P<product>\w+)/(?P<project_id>\w+)/$',
    'tool.views.ProjectConfig',
    name='project_config'
),

views.py:

def ProjectConfig(request, product, project_id=None, template_name='project.html'):
    ...
    # do stuff

project_id問題は、パラメータをオプションにしたいということです。

私は、同じように有効なURLパターンであり/project_config/たいので、渡された場合はそれを使用できます。/project_config/12345abdce/ project_id

現時点では、project_idパラメータなしでURLにアクセスすると404が表示されます。

4

7 に答える 7

441

いくつかのアプローチがあります。

1つは、正規表現で非キャプチャグループを使用することです。正規表現 (?:/(?P<title>[a-zA-Z]+)/)?
DjangoURLトークンをオプションにする

もう1つの、より簡単な方法は、ニーズに一致する複数のルールを用意し、すべてが同じビューを指すようにすることです。

urlpatterns = patterns('',
    url(r'^project_config/$', views.foo),
    url(r'^project_config/(?P<product>\w+)/$', views.foo),
    url(r'^project_config/(?P<product>\w+)/(?P<project_id>\w+)/$', views.foo),
)

ビューでは、オプションのURLパラメータのデフォルトも設定する必要があることに注意してください。そうしないと、エラーが発生します。

def foo(request, optional_parameter=''):
    # Your code goes here
于 2013-01-16T04:03:10.923 に答える
40

Django> 2.0バージョン

アプローチは、Yuji'Tomita'Tomita'sAnswerで与えられたものと本質的に同じです。ただし、影響を受けるのは次の構文です。

# URLconf
...

urlpatterns = [
    path(
        'project_config/<product>/',
        views.get_product, 
        name='project_config'
    ),
    path(
        'project_config/<product>/<project_id>/',
        views.get_product,
        name='project_config'
    ),
]


# View (in views.py)
def get_product(request, product, project_id='None'):
    # Output the appropriate product
    ...

を使用して、タイプがオプションの引数を持つビューに追加の引数を渡すpath()こともできます。この場合、ビューには属性のデフォルトは必要ありません。kwargsdictproject_id

    ...
    path(
        'project_config/<product>/',
        views.get_product,
        kwargs={'project_id': None},
        name='project_config'
    ),
    ...

最新のDjangoバージョンでこれがどのように行われるかについては、URLディスパッチに関する公式ドキュメントを参照してください。

于 2019-01-24T14:13:38.413 に答える
38

ネストされたルートを使用できます

Django <1.8

urlpatterns = patterns(''
    url(r'^project_config/', include(patterns('',
        url(r'^$', ProjectConfigView.as_view(), name="project_config")
        url(r'^(?P<product>\w+)$', include(patterns('',
            url(r'^$', ProductView.as_view(), name="product"),
            url(r'^(?P<project_id>\w+)$', ProjectDetailView.as_view(), name="project_detail")
        ))),
    ))),
)

Django> = 1.8

urlpatterns = [
    url(r'^project_config/', include([
        url(r'^$', ProjectConfigView.as_view(), name="project_config")
        url(r'^(?P<product>\w+)$', include([
            url(r'^$', ProductView.as_view(), name="product"),
            url(r'^(?P<project_id>\w+)$', ProjectDetailView.as_view(), name="project_detail")
        ])),
    ])),
]

これははるかにDRYです(productkwargの名前をに変更したいproduct_id場合は、4行目を変更するだけで、以下のURLに影響します。

Django1.8以降用に編集

于 2014-03-24T22:51:25.473 に答える
32

さらに簡単な方法は次のとおりです。

(?P<project_id>\w+|)

「(a | b)」はaまたはbを意味するため、この場合、1つ以上の単語文字(\ w +)または何もありません。

したがって、次のようになります。

url(
    r'^project_config/(?P<product>\w+)/(?P<project_id>\w+|)/$',
    'tool.views.ProjectConfig',
    name='project_config'
),
于 2014-07-07T12:38:39.627 に答える
10

答えに少し付け加えたいと思いました。

複数のURL定義がある場合は、それぞれに個別に名前を付ける必要があります。したがって、一方のリバースはパラメーターを期待し、もう一方はパラメーターを期待しないため、リバースを呼び出すときの柔軟性が失われます。

オプションのパラメーターに対応するために正規表現を使用する別の方法:

r'^project_config/(?P<product>\w+)/((?P<project_id>\w+)/)?$'
于 2014-02-18T00:51:56.697 に答える
4

Django = 2.2

urlpatterns = [
    re_path(r'^project_config/(?:(?P<product>\w+)/(?:(?P<project_id>\w+)/)/)?$', tool.views.ProjectConfig, name='project_config')
]
于 2019-04-03T16:01:46.307 に答える
0

使用する ?うまく機能し、pythexをチェックできます。ビューメソッドの定義にパラメータ*argsと**kwargsを追加することを忘れないでください

url('project_config/(?P<product>\w+)?(/(?P<project_id>\w+/)?)?', tool.views.ProjectConfig, name='project_config')
于 2020-05-03T17:52:23.303 に答える