Django Testing Framework с декораторами входа в систему - они работают?Ошибка с обратным - PullRequest
3 голосов
/ 23 октября 2009

Я использую среду тестирования Django (которая полезна, но неуклюжа и неуклюжа). Тест продолжает проваливаться, и трассировка заставляет меня поверить, что это проблема с декораторами входа в систему. Вот тесты, ошибка и соответствующий код:

class TestMain(TestCase):
    fixtures = ['timetracker']

    def test_login(self):
        c = Client()
        login = c.login(username='testclient', password='not.a.real.password')
        self.failUnless(login, 'Could not log in')

    def test_main(self):
        c = Client()
        login = c.login(username='testclient', password='not.a.real.password')
        self.failUnless(login, 'Could not log in')

        response = c.get('/', follow=True)
        print response.content
        #assert response.status_code == 200, response.status_code




markov:biorhythm vinceb$ nosetests -v --with-django
test_login (biorhythm.timetracker.tests.test_urls.TestMain) ... ok
test_main (biorhythm.timetracker.tests.test_urls.TestMain) ... ERROR

======================================================================
ERROR: test_main (biorhythm.timetracker.tests.test_urls.TestMain)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/vinceb/Code/python/biorhythm/timetracker/tests/test_urls.py", line 20, 

in test_main
        response = c.get('/', follow=True)
      File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/django/test/client.py", line 281, in get
 [...]
"/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/django/template/__init__.py", line 792, in render_node
        return node.render(context)
      File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/django/template/defaulttags.py", line 382, in render
        raise e
    NoReverseMatch: Reverse for '<django.contrib.auth.decorators._CheckLogin object at 0x22d4650>' with arguments '()' and keyword arguments '{'report_type': u'this_week'}' not found.

----------------------------------------------------------------------
Ran 2 tests in 1.112s

FAILED (errors=1)
Destroying test database...
markov:biorhythm vinceb$ 






@login_required
def time(request):
    # initials
    from biorhythm.timetracker.forms import TimeForm, TimeFormSet
    from django.forms.formsets import formset_factory

    # instantiate our formset factory
    TimeSet = formset_factory(TimeForm, extra=1)
    formset = None

    # sorting worklogs
    order_by = ordered(request)
    success = None

Что действительно странно, так это то, что в запрос вставляются ключевые слова, и это заставляет меня думать, что это шаблонный запрос.

РЕДАКТИРОВАТЬ: больше кода

urlpatterns = patterns('biorhythm.timetracker.views',

    # Home
    url(r'^/?$', 'time', name='home'),

    # CSV exports
    url(r'^reports/csv/(?P<from_date>\d{8})/(?P<to_date>\d{8})/?$', 'export_csv_report', name='csv_out'),   
    url(r'^dashboard/csv/?$', 'export_qbcsv', name='csv_report'),

    # Reports
    url(r'^summary/?$', 'reports', name='reports'),
    (r'^summary/(?P<from_date>\d{8})/(?P<to_date>\d{8})/?$', 'reports'),
    (r'^summary/(?P<report_type>.*?)/?$', 'reports'),

    # test
    (r'new_dashboard/$', 'new_dashboard'),
    url(r'remove_query/(?P<position>.*?)/$', 'remove_query', name='remove_query'),


    # Aggregate timesheets
    url(r'^dashboard/$', 'new_dashboard', name='dashboard'),
    url(r'old_dashboard/$', 'dashboard', name='old_dashboard'),
    (r'^dashboard/(?P<user_id>.*?)/?$', 'dashboard'),
    (r'^dashboard/(?P<from_date>\d{8})/(?P<to_date>\d{8})/?$', 'dashboard'),
)



@login_required
def time(request):
    # initials
    from biorhythm.timetracker.forms import TimeForm, TimeFormSet
    from django.forms.formsets import formset_factory

    # instantiate our formset factory
    TimeSet = formset_factory(TimeForm, extra=1)
    formset = None

    # sorting worklogs
    order_by = ordered(request)
    success = None

    if request.method == 'POST':
        from django.contrib.admin.models import LogEntry, ADDITION
        from django.contrib.contenttypes.models import ContentType
        # we have to make sure we have a matching contenttype for this model
        # normally we will, but first entry may not have this
        worklog, created = ContentType.objects.get_or_create(name='worklog', app_label='timetracker', model='worklog')

        # pertinent fields
        dats = 'project duration note category start_date'.split()

        # instantiate formset
        formset = TimeSet(request.POST)
        for i, form in enumerate(formset.forms):
            labs = ['form-%d-%s' % (i, d) for d in dats]
            project, duration, note, category, start_date = [request.POST.get(l, None) for l in labs]
            check_against = [project, duration, note, start_date] 

            # Checks that required fields have been filled with input longer than 0.
            if 0 not in [len(x) for x in check_against]:
                if form.is_valid():
                    project, duration, note, category, start_date = [form.cleaned_data.get(l, None) for l in dats]

                    if None not in check_against:
                        # this is a form we can process & save so let's
                        # get our pk for logging activity
                        instance = form.save(commit=False)
                        if instance:
                            # default values and save again
                            instance.start_date = form.cleaned_data.get('start_date')
                            instance.user = request.user
                            instance.save()

                            # Output a nice message to the client
                            s = 's' if duration > 1 else '' # pluralization!
                            message = "%s hour%s spent %s on %s" % (duration, s, note, project.name)
                            request.user.message_set.create(message=message)

                            # Append this action (addition) to the LogEntry table
                            _send_LogEntry(request.user.pk, worklog.id, worklog.id,
                                           force_unicode(project), message)


                            success = True
                else:
                    # Form _not_ valid. Continue outputting the formset with error messages.
                    pass
            else:
                # Form missing required field
                continue  
        if success is True:
            return http.HttpResponseRedirect(request.get_full_path())

    # get our data
    worklogs = Worklog.objects.select_related().filter(user=request.user.id).order_by(order_by, '-id')
    time_week = worklogs.filter(start_date__gte=start_of_week()).aggregate(Sum('duration'))
    time_day = worklogs.filter(start_date__gte=today()).aggregate(Sum('duration'))
    #time_week = worklogs.filter(start_date__gte=start_of_week()).objects.objects.get_total_time()
    #time_day = worklogs.filter(start_date__gte=today()).objects.get_total_time()

    reports = return_time_report()

    # instantiate projects for initial data for form for the last 14 days
    # was 30 days, now 14 at Nik's request -J
    month = datetime.timedelta(days=14)
    worklog_projects = worklogs.filter(start_date__gte=today()-month)
    projects = dict.fromkeys([p.project for p in worklog_projects]).keys()

    if not formset:
        initial_data = [{'project':p.id, 'start_date':'today'} for p in projects]
        formset = TimeSet(initial=initial_data)
    has_logs = True if int(worklogs.count()) > 0 else False
    logs = paginate(request, worklogs, 'worklogs')
    logs_list = logs.object_list


    # Initialize categories from a query object, so they can be sent to JQuery
    # via JSON to make auto-complete work.
    cat_list = []
    for c in Category.objects.all():
        cat_list.append(dict(id=str(c.id), name=c.name))
    cats = json.dumps(cat_list)


    context = RequestContext(request)
    return render_to_response('log.html', {'formset':formset, 'worklogs':logs_list, 'v':locals(), 't':reports}, context)

Вот и весь вид.

Это огромный пост, поэтому шаблон здесь: http://dpaste.com/110860/

Ответы [ 3 ]

6 голосов
/ 23 октября 2009

Журнал ошибок, о котором там сообщается, говорит вам большую часть того, что вам нужно знать:

Первое, что вы получили:

in test_main
        response = c.get('/', follow=True)

Это означает, что он умирает при попытке обработать этот запрос. Далее:

      File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/django/test/client.py", line 281, in get
 [...]
"/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/django/template/__init__.py", line 792, in render_node
        return node.render(context)

Он умирает во время рендеринга узла в шаблоне, что означает, что он получает в шаблон, а не умирает при входе в систему. Последнее:

      File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/django/template/defaulttags.py", line 382, in render
        raise e
    NoReverseMatch: Reverse for '<django.contrib.auth.decorators._CheckLogin object at 0x22d4650>' with arguments '()' and keyword arguments '{'report_type': u'this_week'}' not found.

Возникает исключение при попытке изменить URL в вашем шаблоне, что означает, что вы где-то вызвали тег {% url %} с путем к вашей функции представления и аргументом "this_week", но это не самый подходящий способ вызвать ваш просмотр функции в соответствии с вашим URLconf.

Исправьте тег {% url %} или определение функции просмотра, и оно будет работать.

1 голос
/ 23 октября 2009

Вы проверяли свои регулярные выражения в urls.py? Может быть, это фальшивка.

Также проверьте этот билет на ошибку Реверс для объекта 'не найден

Btw. это то, что говорит исходный код django в строке 382 в defaulttags.py

# Try to look up the URL twice: once given the view name, and again
# relative to what we guess is the "main" app. If they both fail,
# re-raise the NoReverseMatch unless we're using the
# {% url ... as var %} construct in which cause return nothing.
0 голосов
/ 23 октября 2009

В вашем файле settings.py определен LOGIN_URL?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...