Python (Django)如何将两个URL映射到一个视图?

Python (Django)如何将两个URL映射到一个视图?,python,django,django-views,django-urls,Python,Django,Django Views,Django Urls,这是models.py中的我的课程: class Person(models.Model): name = models.CharField(max_length=64) persnr = models.AutoField(primary_key=True) 我的看法是: def show_person(request, persnr): pers = get_object_or_404(Person, pk=persnr) context={'pers':pe

这是models.py中的我的课程:

class Person(models.Model):
    name = models.CharField(max_length=64)
    persnr = models.AutoField(primary_key=True)
我的看法是:

def show_person(request, persnr):
    pers = get_object_or_404(Person, pk=persnr)
    context={'pers':pers}
    return render(request, 'company/person.html', context)
这是我的网址:

url(r'^show_person/(?P<persnr>\d+)', "company.views.show_person", name='show_person'),
url(r'^show\u person/(?P.*),“company.views.show\u person”,name='show\u person'),
def显示人员(请求、人员):
per=Person.objects.filter(Q(name=persnr)| Q(persnr=persnr)).all()
上下文={'pers':pers}
返回呈现(请求'company/person.html',上下文)
您可以这样做

pers = get_object_or_404(Person, Q(name=persnr)|Q(persnr=persnr))

我认为将两个URL映射到同一个视图函数会更清楚:

url(r'^show_person/(?P<persnr_or_name>\d+)', "company.views.show_person", name='show_person'),
url(r'^show_person/(?P<persnr_or_name>.*)', "company.views.show_person", name='show_person'),


def show_person(request, persnr_or_name):
    if persnr_or_name.isdigit():
        pers = get_object_or_404(Person, pk=persnr_or_name)
    else:
        pers = get_object_or_404(Person, name=persnr_or_name)
    context={'pers':pers}
    return render(request, 'company/person.html', context)
url(r'^show_person/(?P\d+),“company.views.show_person”,name='show_person'),
url(r'^show_person/(?P.*),“company.views.show_person”,name='show_person'),
def显示人员(请求、人员或姓名):
如果persnr_或_name.isdigit():
pers=获取对象或404(个人,主键=个人或姓名)
其他:
pers=获取对象或404(个人,姓名=个人或姓名)
上下文={'pers':pers}
返回呈现(请求'company/person.html',上下文)
还有一个假设,你们不允许像大多数网站一样使用纯数字

但对我来说,我更喜欢:

url(r'^show_person/(?P<persnr_or_name>\d+)', "company.views.show_person", name='show_person_by_pk'),
url(r'^show_person/(?P<persnr_or_name>.*)', "company.views.show_person", name='show_person_by_name'),


def show_person_by_pk(request, pk):
    pers = Person.objects.get_or_404(pk)
    context={'pers':pers}
    return render(request, 'company/person.html', context)

def show_person_by_name(request, name):
    pers = get_object_or_404(Person, name=name)
    context={'pers':pers}
    return render(request, 'company/person.html', context)
url(r'^show_person/(?P\d+),“company.views.show_person”,name='show_person'by_pk'),
url(r'^show_person/(?P.*),“company.views.show_person”,name='show_person'by_name'),
def按主键显示主键(请求,主键):
pers=Person.objects.get_或_404(主键)
上下文={'pers':pers}
返回呈现(请求'company/person.html',上下文)
def按姓名显示人员(请求、姓名):
pers=获取对象或404(个人,姓名=姓名)
上下文={'pers':pers}
返回呈现(请求'company/person.html',上下文)

如果您愿意,查看代码可以缩短为2行。

稍微不同的方法是接受两个单独的参数,一个用于pk,一个用于名称:

url(r'^show_person/(?P<persnr>\d+)', "company.views.show_person", name='show_person'),
url(r'^show_person/(?P<name>\w+)', "company.views.show_person", name='show_person'),

def show_person(request, persnr=None, name=None):
    if persnr is not None:
        pers = get_object_or_404(Person, pk=persnr)
    elif name is not None:
        pers = get_object_or_404(Person, name=name)
    else:
        raise Http404
url(r'^show_person/(?P\d+),“company.views.show_person”,name='show_person'),
url(r'^show_person/(?P\w+),“company.views.show_person”,name='show_person'),
def show_person(请求,persnr=None,name=None):
如果persnr不是None:
pers=获取对象或404(Person,pk=persnr)
elif名称不是无:
pers=获取对象或404(个人,姓名=姓名)
其他:
提高Http404

是什么阻止您创建另一个捕获该名称的URL?当然,这是行不通的,因为视图需要PK,所以不清楚为什么您希望两个URL都指向同一个视图。我尝试过,但不知道如何修复预期pkI的错误。pkI建议不要使用相同URL的两个相同页面。你应该选择一个你喜欢的,然后重定向另一个。例如,
show_person/123
show_person/john smith
。这里不需要两个URL。不管怎样,您正在使用
isinstance
进行检查
*
对于您的
视图来说已经足够了
@itzmeontv如果您在URL模块中定义它们,会比在视图模块中定义它们更清晰。这是我在编程中一直比较喜欢的——声明比渐进式更好。好。但是
persnr\u或\u name
将同时使用这两个选项,因为您声明了这一点。因此,在声明的意义上,不要再有否定的东西了。否则你应该分别做
pernr
name
。还有
(?P\d+
无论如何都不接受名称。这不起作用;参数将始终是字符串,即使它捕获的值是数字。您需要尝试将其转换为int并捕获错误。@DanielRoseman您是对的,我已经解决了这个问题。您的答案与我经过几次思考后的想法相同。不理解这种方式。为什么使用IF语句?:)或:
(?P\d+)
def show_person(请求,**kwargs):…获取对象或_404(person,**kwargs)
:-)@Marin url端点(绿色)可以接受
persnr
name
。如果它们包含
persnr
,则将执行If语句。如果它们包含
名称
,则将执行elif语句。如果未提供任何信息,将引发Http404
url(r'^show_person/(?P<persnr_or_name>\d+)', "company.views.show_person", name='show_person_by_pk'),
url(r'^show_person/(?P<persnr_or_name>.*)', "company.views.show_person", name='show_person_by_name'),


def show_person_by_pk(request, pk):
    pers = Person.objects.get_or_404(pk)
    context={'pers':pers}
    return render(request, 'company/person.html', context)

def show_person_by_name(request, name):
    pers = get_object_or_404(Person, name=name)
    context={'pers':pers}
    return render(request, 'company/person.html', context)
url(r'^show_person/(?P<persnr>\d+)', "company.views.show_person", name='show_person'),
url(r'^show_person/(?P<name>\w+)', "company.views.show_person", name='show_person'),

def show_person(request, persnr=None, name=None):
    if persnr is not None:
        pers = get_object_or_404(Person, pk=persnr)
    elif name is not None:
        pers = get_object_or_404(Person, name=name)
    else:
        raise Http404