我已经构建了一个测试用例,用于在访问多个pk值时演示django url和基于类的视图的问题。
演示此问题的文件是addressbook/family/templates/family/family_detail.html
,我已经注释了我的尝试。
我想从家庭详细信息页面链接到特定的人,但第一次评论的尝试提供了NoReverseMatch at /family/2/ . Reverse for 'person-detail' with arguments '(1,)' and keyword arguments '{}' not found. 1 pattern(s) tried: ['family/(?P<pk>\\d+)/person/(?P<pk>\\d+)/$']
第二次及其第三次评论尝试在服务器上旋转很长时间,然后最终给出error at /family/1/patient/1/
redefinition of group name 'pk' as group 2; was group 1
项目结构是:
addressbook/
addressbook/
urls.py
family/
models.py
urls.py
views.py
templates/family/
family_detail.html
family_form.html
family_list.html
person/
models.py
urls.py
views.py
templates/person/
person_detail.html
person_form.html
addressbook/addressbook/urls.py
from django.conf.urls import patterns, include, url
urlpatterns = patterns('',
url(r'^family/',include('family.urls',namespace='family')),
)
addresbook/family/models.py
from django.db import models
class Family(models.Model):
lastname=models.CharField(max_length=100)
def __str__(self):
return self.lastname
addressbook/family/urls.py
from django.conf.urls import include, patterns, url
from .views import FamilyCreateView, FamilyDetailView, FamilyListView
urlpatterns=patterns('',
url(r'^$',FamilyListView.as_view(),name='family-list'),
url(r'^create/$',FamilyCreateView.as_view(),name='family-create'),
url(r'^(?P<pk>\d+)/$',FamilyDetailView.as_view(),name='family-detail'),
url(r'^(?P<pk>\d+)/person/',include('person.urls',namespace='person')),
)
addressbook/family/views.py
from django.views import generic
from django.core.urlresolvers import reverse
from .models import Family
class FamilyListView(generic.ListView):
context_object_name='family_list'
model=Family
class FamilyDetailView(generic.DetailView):
context_object_name='family'
model=Family
class FamilyCreateView(generic.CreateView):
model=Family
def get_success_url(self,**kwargs):
return reverse('family-detail',kwargs={'pk':self.object.pk})
addressbook/family/templates/family/family_detail.html
{% extends "base.html" %}
{% block content %}
<h1>{{ family }}</h1>
<ul>
{% for person in family.person_set.all %}
<li>{{ person }}</li>
{#<li><a href="{% url 'family:person:person-detail' person.pk %}">{{ person }}</a></li>#}
{#<li><a href="{% url 'family:person:person-detail' person.family.pk person.pk %}">{{ person }}</a></li>#}
{#<li><a href="{% url 'family:person:person-detail' pk=person.family.pk pk=person.pk %}">{{ person }}</a></li>#}
{% endfor %}
</ul>
<br><br><br>
<p><a href="{% url 'family:person:person-create' family.pk %}">Add family member</a></p>
<p><a href="{% url 'family:family-list' %}">Return to family list</a><p>
{% endblock content %}
addressbook/family/templates/family/family_form.html
{% extends "base.html" %}
{% block content %}
<h1>Add/Update Family</h1>
<form method="POST">{% csrf_token %}
{{ form }}
<p><button type="submit">Save</button></p>
</form>
<br><br><br>
<p><a href="{% url 'family:family-list' %}">Return to family list</a></p>
{% endblock content %}
addressbook/family/templates/family/family_list.html
{% extends "base.html" %}
{% block content %}
{% for family in family_list %}
<ul>
<li><a href="{% url 'family:family-detail' family.id %}">{{ family }}</a></li>
</ul>
{% endfor %}
<br><br><br>
<a href="{% url 'family:family-create' %}">Create new family</a>
{% endblock content %}
addressbook/person/models.py
from django.db import models
from family.models import Family
class Person(models.Model):
family=models.ForeignKey(Family)
firstname=models.CharField(max_length=100)
def __str__(self):
return self.firstname
addressbook/person/urls.py
from django.conf.urls import patterns, url
from .views import PersonCreateView, PersonDetailView
urlpatterns=patterns('',
url(r'^create/$', PersonCreateView.as_view(),name='person-create'),
url(r'^(?P<pk>\d+)/$',PersonDetailView.as_view(),name='person-detail'),
)
addressbook/person/views.py
from django.views import generic
from django.core.urlresolvers import reverse
from django.shortcuts import get_object_or_404
from .models import Person
from family.models import Family
class PersonDetailView(generic.DetailView):
model=Person
class PersonCreateView(generic.CreateView):
model=Person
def get_initial(self):
family=get_object_or_404(Family,pk=self.kwargs.get('pk'))
return {'family':family,}
def get_success_url(self,**kwargs):
return reverse('family:family-detail',args=[self.kwargs['pk']])
#return reverse('person-detail',kwargs={'pk':self.object.pk})
addressbook/person/templates/person/person_detail.html:
{% extends "base.html" %}
{% block content %}
{{ person }} {{ person.family }}
<br><br>
<p><a href="{% url 'family:family-detail' person.family.pk %}">Return to family: {{ person.family }}</a></p>
{% endblock content %}
addressbook/person/templates/person/person_form.html
{% extends "base.html" %}
{% block content %}
<h1>Add/Update Person</h1>
<form method="POST">{% csrf_token %}
{{ form }}
<p><button type="submit">Save</button></p>
</form>
<br><br><br>
{#<p><a href="{% url 'family:family-detail' family.pk %}">Return to family {{ family }}</a></p>#}
{% endblock content %}
答案 0 :(得分:4)
您需要重新考虑您的网址。希望以下评论会有所帮助。
在您的家庭网址中
url(r'^(?P<pk>\d+)/person/',include('person.urls',namespace='person')),
然后在你的网址中你有
url(r'^(?P<pk>\d+)/$',PersonDetailView.as_view(),name='person-detail'),
这表示/family/<pk>/person/<pk>/
形式的网址。这是无效的,因为您在同一模式中使用了两次命名参数pk。
如果您在网址格式中重命名其中一个主键,例如:
url(r'^(?P<person_pk>\d+)/$',PersonDetailView.as_view(),name='person-detail'),
然后您可以在PersonDetail视图中使用pk_url_kwarg
选项。
class PersonDetailView(generic.DetailView):
model=Person
pk_url_kwarg = 'person_pk'
另请注意,上面的url中有两个参数,但是当您尝试反转模板中的url时,只提供一个参数。你在哪里
<a href="{% url 'family:person:person-detail' person.pk %}">{{ person }}</a>
你需要提供家庭PK和人pk:
<a href="{% url 'family:person:person-detail' family.pk person.pk %}">{{ person }}</a>