[英]Django Not matching URL, No Reverse Match
我在Django項目中使用的是基於TDD的方法,這是一個自制材料的數據庫。 我已經能夠通過功能測試和單元測試添加躍點記錄。 我遇到的問題是更新視圖功能(編輯現有記錄)。 我以前使用基於類的視圖完成了此操作,但遇到了一些我無法避免的錯誤,這就是為什么我使用TDD /函數視圖方法而不是直接使用CBV的原因。
我目前收到以下錯誤,指示我的視圖beerdb/edit/(?P<pk>\\\\d+)/hops/$
沒有反向匹配。 因此,我在我的Hop模型上創建了一個get_absolute_url方法:
def get_absolute_url(self):
return reverse('updatehops', kwargs={'pk': self.id})
返回該反向URL:
django.core.urlresolvers.NoReverseMatch: Reverse for 'updatehops' with arguments '()' and keyword arguments '{'pk': ''}' not found. 1 pattern(s) tried: ['beerdb/edit/(?P<pk>\\d+)/hops/$']
這是我的測試,其結果是上面的錯誤:
def test_can_update_hops(self):
self.client.post(
'/beerdb/add/hops/',
data={
'name': 'Warrior',
'min_alpha_acid': 24.00,
'max_alpha_acid': 32.00,
'country': 'USA',
'comments': 'Very bitter, not good for aroma'
})
hop_instance = Hop.objects.filter(name='Warrior')[0]
response = self.client.get('/beerdb/edit/%d/hops/' % hop_instance.id)
self.assertEqual(response.status_code, 200)
我的其他項目詳細信息如下。 誰能指出我可能會出問題的地方? 我也認為我的urls.py可能需要修改。 我不太清楚如何返回帶有模板的反向URL。 我已經查看了render,render_to_response,redirect和HttpResponseRedirect對象,但看不到如何返回該上下文。 在基於類的視圖中,我將調用super方法並獲取上下文數據,並將主鍵添加到“ action”中,但是我不知道如何在這里應用它。
項目詳情
urls.py
urlpatterns = [
url(r'^$', views.homebrewmain, name='beerdb_main'),
url(r'^hops/$', views.hops, name='hops_list'),
url(r'^add/hops/$', views.addhops, name='addhops'),
url(r'^edit/(?P<pk>\d+)/hops/$', views.updatehops, name='updatehops')
]
models.py
class Hop(models.Model):
name = models.CharField(max_length=200, default='')
min_alpha_acid = models.DecimalField(max_digits=4, decimal_places=2)
max_alpha_acid = models.DecimalField(max_digits=4, decimal_places=2)
# Country codes for origin (as defined by http://countrycode.org)
AUSTRALIA = 'AUS'
CANADA = 'CAN'
CHINA = 'CHN'
CZECH_REPUBLIC = 'CZE'
FRANCE = 'FRA'
GERMANY = 'DEU'
NEW_ZEALAND = 'NZL'
POLAND = 'POL'
UNITED_KINGDOM = 'GBR'
UNITED_STATES = 'USA'
COUNTRY_CODES = (
(AUSTRALIA, 'Australia'),
(CANADA, 'Canada'),
(CHINA, 'China'),
(CZECH_REPUBLIC, 'Czech Republic'),
(FRANCE, 'France'),
(GERMANY, 'Germany'),
(NEW_ZEALAND, 'New Zealand'),
(POLAND, 'Poland'),
(UNITED_KINGDOM, 'United Kingdom'),
(UNITED_STATES, 'United States'),
)
country = models.CharField(max_length=3,
choices=COUNTRY_CODES,
default=UNITED_STATES
)
comments = models.TextField(default='')
def get_absolute_url(self):
return reverse('updatehops', kwargs={'pk': self.id})
編輯:我已經更新了我的視圖函數,以返回沒有點符號的反向URL重定向:
def updatehops(request, pk):
hop_record = Hop.objects.filter(pk=pk)[0]
edit_form = HopForm(request.POST or None, instance=hop_record)
if request.method == 'POST':
if edit_form.is_valid():
edit_form.save()
success_url = reverse('hops_list')
return HttpResponseRedirect(success_url)
hop_form_url = reverse('updatehops', kwargs={'pk': hop_record.id})
return redirect(hop_form_url)
正如我在下面的評論中所指出的,如果我在響應上聲明status_code = 302,這將使測試通過,但是我需要200來確保已獲取呈現的表單,以便可以訪問響應中的內容,並更改其中的一些內容。稍后再編寫其余測試時,數據並重新保存。
更新:經過研究后,我修改了網址,以便現在將其傳遞給hop_id而不是<pk>
:
url(r'^edit/(?P<pk>\d+)/hops/$', views.updatehops, name='updatehops'),
我仍然遇到錯誤,但在錯誤消息中收到了pk:
django.core.urlresolvers.NoReverseMatch: Reverse for 'updatehops' with arguments '()' and keyword arguments '{'pk': 7}' not found. 1 pattern(s) tried: ['beerdb/edit/(?P<hop_id>\\d+)/hops/$']
編輯2:我已將'pk'添加回URL,添加了回溯
追溯
Template error:
In template /Path/To/Site/Site/homebrewdatabase/templates/homebrewdatabase/hops.html, error at line 23
Reverse for 'updatehops' with arguments '()' and keyword arguments '{'pk': ''}' not found. 1 pattern(s) tried: ['beerdb/edit/(?P<pk>\\d+)/hops/$']
13 : {% include 'homebrewdatabase/addhops.html' %}
14 :
15 : <!--Modal data begins here to edit hops-->
16 : <div class="modal fade" id="updatehops" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
17 : <div class="modal-dialog" role="document">
18 : <div class="modal-content">
19 : <div class="modal-header">
20 : <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
21 : <h4 class="modal-title" id="myModalLabel">Add Hops</h4>
22 : </div>
23 : <form action=" {% url 'homebrewdatabase:updatehops' pk=hop.id %} " method="POST">
24 : <div class="modal-body">
25 : {{ form.as_p }}
26 : {% csrf_token %}
27 : </div>
28 : <div class="modal-footer">
29 : <button type="button" id="close" class="btn btn-default" data-dismiss="modal">Close</button>
30 : <button type="submit" id="submit" class="btn btn-primary">Submit</button>
31 : </form>
32 : </div>
33 : </div>
如果您希望測試客戶端遵循重定向,請使用follow=True
。
response = self.client.post(
'/beerdb/add/hops/',
data={...},
follow=True,
)
然后,您可以檢查響應的內容。 如果然后要測試重定向,則可以使用assertRedirects
而不是檢查狀態碼。
這里有一些有關反向URL的技巧。 首先,使用URL模式名稱,例如updatehops
,而不是視圖的完整路徑'homebrewdatabase.views.updatehop'
。 其次,確保您的矮人匹配。 您的網址中有hop_id
。 因此,您需要
reverse('updatehops', kwargs={'hop_id': hop_record.id})
response = self.client.get('/beerdb/edit/%d/hops/' % hop_instance.id)
在測試代碼的上一行中,不應在行上方將其命名為beerdb_main,而應僅是Beerdb。
僅供參考:我指的是您代碼的測試部分。
您必須這樣做: reverse('updatehops')
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.