2013-03-20 46 views
0

我有一個視圖 - 名爲DevicesListView - 在測試環境中執行時沒有問題(在Webtest中),但是當我嘗試在開發環境中執行相同的視圖時,我收到一個NoReverseMatch錯誤。NoReverseError在開發環境中,但未在測試

設備/ urls.py

from inventory.devices.views import DeviceCheckout 
urlpatterns = patterns('', 
    # NOTE: these are namespaced as 'devices' 

    # ex: /devices 
    url(r'^$', 
     DevicesListView.as_view(), 
     name='index'), 

    # ex: /devices/3/checkout 
    url(r'^(?P<pk>\d)/checkout/$', 
     DeviceCheckout.as_view(), 
     name='checkout'), 
) 

views.py

class DevicesListView(ListView): 
    '''Index view for devices.''' 
    model = Device 
    template_name = 'devices/index.html' 
    context_object_name = 'all_devices' 
    def get(self, request): 
     # ... 
    def post(self, request): 
     """Process the action for the selected devices. 
     """ 
     action = request.POST['action'] # the selected action 
     # Get the IDs of the devices that had their checkboxes selected 
     selected_pks = [int(v) for v in request.POST.getlist('device_select')] 
     # Get the selected Device objects 
     selected_devices = Device.objects.filter(pk__in=selected_pks) 
     # ... Logic to handle selected action ... 
     # redirect to lendee selection page 
     device = selected_devices[0] 
     if action == 'checkout_selected': 
      return redirect('devices:checkout', pk=device.pk) # throws NoReverseMatch in development 
     elif action == 'checkin_selected': 
      return redirect('devices:checkin', pk=device.pk) 
     return redirect('devices:index') 

webtest_tests.py

from django_webtest import WebTest 
from inventory.user.tests.factories import UserFactory 
from inventory.devices.tests.factories import DeviceFactory 
class TestAUser(WebTest): 
    def setUp(self): 
     self.user = UserFactory() 

    def test_can_checkout_device(self): 
     # two devices are already created 
     DeviceFactory() 
     DeviceFactory() 
     # goes to devices page 
     res = self.app.get('/devices', user=self.user) 
     # checks the first device 
     form = res.forms['device_control'] 
     form.set('device_select', True, index=0) 
     # Selects Checkout device 
     form.set('action', 'checkout_selected') 
     # Submits form 
     res = form.submit().follow() 
     assert_equal(res.status_code, 200) # PASSES 

個設備/ index.html的

<form method="post" id="device_control" action=""> 
    {% csrf_token %} 
    <label><span class="action-label">Action:</span> 
     <select name="action"> 
     <option value="" selected="selected">---------</option> 
     <option value="checkout_selected">Checkout</option> 
     <option value="checkin_selected">Checkin</option> 
     <option value="delete_selected">Delete selected</option> 
     </select> 
    </label> 
    <input type="submit" name="_save" class="default btn" value="Go"/> 
    </div><!-- end btn-toolbar --> 
    <table class='table table-striped'> 
    <thead> 
     <th>Select</th> 
     <th>Name</th> 
    </thead> 
    <tbody> 
    {% for device in all_devices %} 
     <tr> 
     <td><input type="checkbox" value="{{ device.pk }}" name='device_select' id="select_device{{ device.pk }}"></td> 
     <td>{{ device.name }}</td> 
     </tr> 
    {% endfor %} 
    </tbody> 
    </table> 
</form> 

模板的錯誤,我得到的是:

NoReverseMatch at /devices/ 
Reverse for 'checkout' with arguments '()' and keyword arguments '{'pk': 13}' not found. 

我已經確定要執行syncdb並重新啓動開發服務器。什麼會在測試和開發環境之間導致這種不同的行爲?我在Mac OSX Lion上使用Django 1.5。

回答

0

確實是一個愚蠢的錯誤。問題出在url模式的正則表達式中。 r'^(?P<pk>\d)/checkout/$'只捕獲1位數的PK。它在\d之後錯過了+。所以它應該是:

... 
# ex: /devices/13/checkout 
url(r'^(?P<pk>\d+)/checkout/$', 
    DeviceCheckout.as_view(), 
    name='checkout'), 
...