开发环境中的NoReverseError,但不在测试中

时间:2013-03-20 18:26:07

标签: django django-webtest

我有一个视图 - 下面称为DevicesListView - 在测试环境中(在Webtest中)执行没有问题,但是当我尝试在开发环境中执行相同的视图时,我得到NoReverseMatch错误。

设备/ 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。

1 个答案:

答案 0 :(得分:0)

确实是一个愚蠢的错误。问题出在网址模式正则表达式中。 r'^(?P<pk>\d)/checkout/$'只捕获1位数的pk。在+之后错过了\d。所以它应该是:

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