Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
thalia
concrexit
Commits
e31fea84
Unverified
Commit
e31fea84
authored
Aug 29, 2018
by
Thom Wiggers
📐
Browse files
Document and clean up thaliawebsite module
Closes
#586
parent
d370b125
Changes
17
Hide whitespace changes
Inline
Side-by-side
website/thaliawebsite/__init__.py
View file @
e31fea84
"""
The main module for the Thalia website.
This module defines settings and the URI layout.
We also handle some site-wide API stuff here.
"""
from
__future__
import
absolute_import
,
unicode_literals
from
__future__
import
absolute_import
,
unicode_literals
# This will make sure the app is always imported when
# This will make sure the app is always imported when
...
...
website/thaliawebsite/admin.py
View file @
e31fea84
"""Settings for the admin site"""
from
django.contrib
import
admin
from
django.contrib
import
admin
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.translation
import
ugettext_lazy
as
_
...
...
website/thaliawebsite/celery.py
View file @
e31fea84
"""Celery entry point"""
from
__future__
import
absolute_import
,
unicode_literals
from
__future__
import
absolute_import
,
unicode_literals
import
os
import
os
from
celery
import
Celery
from
celery
import
Celery
...
@@ -5,7 +6,7 @@ from celery import Celery
...
@@ -5,7 +6,7 @@ from celery import Celery
# set the default Django settings module for the 'celery' program.
# set the default Django settings module for the 'celery' program.
os
.
environ
.
setdefault
(
'DJANGO_SETTINGS_MODULE'
,
'thaliawebsite.settings'
)
os
.
environ
.
setdefault
(
'DJANGO_SETTINGS_MODULE'
,
'thaliawebsite.settings'
)
app
=
Celery
(
'thaliawebsite'
)
app
=
Celery
(
'thaliawebsite'
)
# pylint: disable=invalid-name
# Using a string here means the worker doesn't have to serialize
# Using a string here means the worker doesn't have to serialize
# the configuration object to child processes.
# the configuration object to child processes.
...
...
website/thaliawebsite/context_processors.py
View file @
e31fea84
...
@@ -6,4 +6,5 @@ import os
...
@@ -6,4 +6,5 @@ import os
def
source_commit
(
_
):
def
source_commit
(
_
):
"""Get the SOURCE_COMMIT environment variable"""
return
{
'SOURCE_COMMIT'
:
os
.
environ
.
get
(
'SOURCE_COMMIT'
,
'unknown'
)}
return
{
'SOURCE_COMMIT'
:
os
.
environ
.
get
(
'SOURCE_COMMIT'
,
'unknown'
)}
website/thaliawebsite/forms.py
View file @
e31fea84
"""Special forms"""
from
django.contrib.auth.forms
import
(
AuthenticationForm
as
from
django.contrib.auth.forms
import
(
AuthenticationForm
as
BaseAuthenticationForm
)
BaseAuthenticationForm
)
class
AuthenticationForm
(
BaseAuthenticationForm
):
class
AuthenticationForm
(
BaseAuthenticationForm
):
def
__init__
(
self
,
request
=
None
,
*
args
,
**
kwargs
):
"""Override the authentication form provided by Django"""
super
(
AuthenticationForm
,
self
).
__init__
(
request
,
*
args
,
**
kwargs
)
def
clean
(
self
):
def
clean
(
self
):
"""Lowercase the username"""
if
'username'
in
self
.
cleaned_data
:
if
'username'
in
self
.
cleaned_data
:
self
.
cleaned_data
[
'username'
]
=
(
self
.
cleaned_data
[
'username'
]
self
.
cleaned_data
[
'username'
]
=
(
self
.
cleaned_data
[
'username'
]
.
lower
())
.
lower
())
...
...
website/thaliawebsite/menus.py
View file @
e31fea84
"""
This file defines the menu layout.
We set the variable `:py:main` to form the menu tree.
"""
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.translation
import
ugettext_lazy
as
_
main
=
[
__all__
=
[
'MAIN_MENU'
]
#: Defines the menu layout as a nested dict.
#:
#: The authenticated key indicates something should only
#: be visible for logged-in users. **Do not** rely on that for
#: authentication!
MAIN_MENU
=
[
{
'title'
:
_
(
'Home'
),
'name'
:
'index'
},
{
'title'
:
_
(
'Home'
),
'name'
:
'index'
},
{
'title'
:
_
(
'Association'
),
'name'
:
'association'
,
'submenu'
:
[
{
{
'title'
:
_
(
'Board'
),
'name'
:
'activemembers:boards'
},
'title'
:
_
(
'Association'
),
{
'title'
:
_
(
'Committees'
),
'name'
:
'activemembers:committees'
},
'name'
:
'association'
,
{
'title'
:
_
(
'Documents'
),
'name'
:
'documents:index'
},
'submenu'
:
[
{
'title'
:
_
(
'Merchandise'
),
'name'
:
'merchandise:index'
},
{
'title'
:
_
(
'Board'
),
'name'
:
'activemembers:boards'
},
{
'title'
:
_
(
'Sister Associations'
),
'name'
:
'sister-associations'
},
{
'title'
:
_
(
'Committees'
),
'name'
:
'activemembers:committees'
},
{
'title'
:
_
(
'Become a Member'
),
'name'
:
'registrations:index'
},
{
'title'
:
_
(
'Documents'
),
'name'
:
'documents:index'
},
{
'title'
:
_
(
'Thabloid'
),
'name'
:
'thabloid:index'
},
{
'title'
:
_
(
'Merchandise'
),
'name'
:
'merchandise:index'
},
]},
{
'title'
:
_
(
'Sister Associations'
),
'name'
:
'sister-associations'
},
{
'title'
:
_
(
'For Members'
),
'name'
:
'for-members'
,
{
'title'
:
_
(
'Become a Member'
),
'name'
:
'registrations:index'
},
{
'title'
:
_
(
'Thabloid'
),
'name'
:
'thabloid:index'
},
],
},
{
'title'
:
_
(
'For Members'
),
'name'
:
'for-members'
,
'submenu'
:
[
{
'title'
:
_
(
'Member list'
),
'name'
:
'members:index'
},
{
'title'
:
_
(
'Photos'
),
'name'
:
'photos:index'
},
{
'title'
:
_
(
'Statistics'
),
'name'
:
'statistics'
},
{
'title'
:
_
(
'Styleguide'
),
'name'
:
'styleguide'
},
{
'title'
:
_
(
'Become Active'
),
'name'
:
'become-active'
},
{
'title'
:
_
(
'Wiki'
),
'url'
:
'/wiki/'
,
'authenticated'
:
True
},
],
},
{
'title'
:
_
(
'Calendar'
),
'name'
:
'events:index'
,
'submenu'
:
[
{
'title'
:
_
(
'Order Pizza'
),
'name'
:
'pizzas:index'
},
],
},
{
'title'
:
_
(
'Career'
),
'name'
:
'partners:index'
,
'submenu'
:
[
'submenu'
:
[
{
'title'
:
_
(
'Member list'
),
'name'
:
'members:index'
},
{
'title'
:
_
(
'Partners'
),
'name'
:
'partners:index'
},
{
'title'
:
_
(
'Photos'
),
'name'
:
'photos:index'
},
{
'title'
:
_
(
'Vacancies'
),
'name'
:
'partners:vacancies'
},
{
'title'
:
_
(
'Statistics'
),
'name'
:
'statistics'
},
],
{
'title'
:
_
(
'Styleguide'
),
'name'
:
'styleguide'
},
},
{
'title'
:
_
(
'Become Active'
),
'name'
:
'become-active'
},
{
{
'title'
:
_
(
'Wiki'
),
'url'
:
'/wiki/'
,
'authenticated'
:
True
},
'title'
:
_
(
'Education'
),
]},
'name'
:
'education:index'
,
{
'title'
:
_
(
'Calendar'
),
'name'
:
'events:index'
,
'submenu'
:
[
'submenu'
:
[
{
'title'
:
_
(
'Order Pizza'
),
'name'
:
'pizzas:index'
},
{
'title'
:
_
(
'Book Sale'
),
'name'
:
'education:books'
},
]},
{
{
'title'
:
_
(
'Career'
),
'name'
:
'partners:index'
,
'submenu'
:
[
'title'
:
_
(
'Student Participation'
),
{
'title'
:
_
(
'Partners'
),
'name'
:
'partners:index'
},
'name'
:
'education:student-participation'
{
'title'
:
_
(
'Vacancies'
),
'name'
:
'partners:vacancies'
},
},
]},
{
{
'title'
:
_
(
'Education'
),
'name'
:
'education:index'
,
'submenu'
:
[
'title'
:
_
(
'Course Overview'
),
'name'
:
'education:courses'
,
{
'title'
:
_
(
'Book Sale'
),
'name'
:
'education:books'
},
'submenu'
:
[
{
'title'
:
_
(
'Student Participation'
),
{
'name'
:
'education:student-participation'
},
'title'
:
_
(
'Submit Exam'
),
{
'title'
:
_
(
'Course Overview'
),
'name'
:
'education:courses'
,
'name'
:
'education:submit-exam'
'submenu'
:
[
},
{
'title'
:
_
(
'Submit Exam'
),
'name'
:
'education:submit-exam'
},
{
{
'title'
:
_
(
'Submit Summary'
),
'title'
:
_
(
'Submit Summary'
),
'name'
:
'education:submit-summary'
},
'name'
:
'education:submit-summary'
]},
},
]},
],
},
]
},
{
'title'
:
_
(
'Contact'
),
'name'
:
'contact'
},
{
'title'
:
_
(
'Contact'
),
'name'
:
'contact'
},
]
]
website/thaliawebsite/settings/__init__.py
View file @
e31fea84
...
@@ -6,27 +6,26 @@ This file controls what settings are loaded.
...
@@ -6,27 +6,26 @@ This file controls what settings are loaded.
Using environment variables you can control the loading of various
Using environment variables you can control the loading of various
overrides.
overrides.
"""
"""
# flake8: noqa
import
os
# Load all default settings because we need to use settings.configure
# Load all default settings because we need to use settings.configure
# for sphinx documentation generation.
# for sphinx documentation generation.
from
django.conf.global_settings
import
*
from
django.conf.global_settings
import
*
# pylint: disable=wildcard-import
import
os
# Load base settings
# Load base settings
from
.settings
import
*
from
.settings
import
*
# pylint: disable=wildcard-import
# Attempt to load local overrides
# Attempt to load local overrides
try
:
try
:
from
.localsettings
import
*
from
.localsettings
import
*
# pylint: disable=wildcard-import
except
ImportError
:
except
ImportError
:
pass
pass
# Load production settings if DJANGO_PRODUCTION is set
# Load production settings if DJANGO_PRODUCTION is set
if
os
.
environ
.
get
(
'DJANGO_PRODUCTION'
):
# pragma: nocover
if
os
.
environ
.
get
(
'DJANGO_PRODUCTION'
):
# pragma: nocover
from
.production
import
*
from
.production
import
*
# pylint: disable=wildcard-import
# Load testing settings if GITLAB_CI is set
# Load testing settings if GITLAB_CI is set
if
os
.
environ
.
get
(
'GITLAB_CI'
):
# pragma: nocover
if
os
.
environ
.
get
(
'GITLAB_CI'
):
# pragma: nocover
from
.testing
import
*
from
.testing
import
*
# pylint: disable=wildcard-import
website/thaliawebsite/settings/testing.py
View file @
e31fea84
...
@@ -30,12 +30,12 @@ PASSWORD_HASHERS = (
...
@@ -30,12 +30,12 @@ PASSWORD_HASHERS = (
)
)
# Strip unneeded apps
# Strip unneeded apps
[
INSTALLED_APPS
.
remove
(
x
)
for
x
in
(
_
=
[
INSTALLED_APPS
.
remove
(
x
)
for
x
in
(
'corsheaders'
,
'corsheaders'
,
)]
)]
# Strip unneeded middlewares
# Strip unneeded middlewares
[
MIDDLEWARE
.
remove
(
x
)
for
x
in
(
_
=
[
MIDDLEWARE
.
remove
(
x
)
for
x
in
(
'corsheaders.middleware.CorsMiddleware'
,
'corsheaders.middleware.CorsMiddleware'
,
'django.middleware.http.ConditionalGetMiddleware'
,
'django.middleware.http.ConditionalGetMiddleware'
,
'django.middleware.csrf.CsrfViewMiddleware'
,
'django.middleware.csrf.CsrfViewMiddleware'
,
...
...
website/thaliawebsite/sitemaps.py
View file @
e31fea84
"""Defines site maps."""
from
django.contrib
import
sitemaps
from
django.contrib
import
sitemaps
from
django.urls
import
reverse
from
django.urls
import
reverse
class
StaticViewSitemap
(
sitemaps
.
Sitemap
):
class
StaticViewSitemap
(
sitemaps
.
Sitemap
):
"""Sitemap items for static pages"""
def
items
(
self
):
def
items
(
self
):
return
[
'index'
,
'become-active'
,
'sister-associations'
,
'contact'
]
"""
The items of the site map.
def
location
(
self
,
item
):
:return: the items in the site map
return
reverse
(
item
)
:rtype: [str]
"""
# Need to be valid entries for reverse()
return
[
'index'
,
'become-active'
,
'sister-associations'
,
'contact'
,
]
def
location
(
self
,
obj
):
"""
Get the location for a site map item.
Example::
>>> sitemap = StaticViewSitemap()
>>> sitemap.location(sitemap.items()[0])
:param obj: the item to reverse.
:type obj: str
:return: the URI to the item.
"""
return
reverse
(
obj
)
website/thaliawebsite/templatetags/baseurl.py
View file @
e31fea84
"""Obtain the base url"""
from
django.template
import
Library
from
django.template
import
Library
register
=
Library
()
register
=
Library
()
# pylint: disable=invalid-name
@
register
.
simple_tag
(
takes_context
=
True
)
@
register
.
simple_tag
(
takes_context
=
True
)
def
baseurl
(
context
):
def
baseurl
(
context
):
"""
"""
R
eturn a BASE_URL template context for the current request.
:r
eturn
:
a BASE_URL template context for the current request.
"""
"""
request
=
context
[
'request'
]
request
=
context
[
'request'
]
...
...
website/thaliawebsite/templatetags/bleach_tags.py
View file @
e31fea84
from
__future__
import
absolute_import
,
print_function
,
unicode_literals
"""
Bleach allows to clean up user input to make it safe to display, but
allow some HTML.
"""
from
bleach
import
clean
from
bleach
import
clean
from
django
import
template
from
django
import
template
from
django.template.defaultfilters
import
stringfilter
from
django.template.defaultfilters
import
stringfilter
from
django.utils.safestring
import
mark_safe
from
django.utils.safestring
import
mark_safe
register
=
template
.
Library
()
register
=
template
.
Library
()
# pylint: disable=invalid-name
def
_allow_iframe_attrs
(
tag
,
name
,
value
):
def
_allow_iframe_attrs
(
tag
,
name
,
value
):
"""
Filter to allow certain attributes for tags
:param tag: the tag
:param name: the attribute name
:param value: the value of the item.
"""
# these are fine
if
name
in
(
'class'
,
'width'
,
'height'
,
'frameborder'
,
'allowfullscreen'
):
if
name
in
(
'class'
,
'width'
,
'height'
,
'frameborder'
,
'allowfullscreen'
):
return
True
return
True
elif
tag
==
'iframe'
and
name
==
'src'
:
# youtube is allowed to have `src`
if
tag
==
'iframe'
and
name
==
'src'
:
return
(
value
.
startswith
(
'https://www.youtube.com/embed/'
)
or
return
(
value
.
startswith
(
'https://www.youtube.com/embed/'
)
or
value
.
startswith
(
'https://www.youtube-nocookie.com/embed/'
))
value
.
startswith
(
'https://www.youtube-nocookie.com/embed/'
))
...
...
website/thaliawebsite/templatetags/fieldtype.py
View file @
e31fea84
"""
Get the field type for a form field
"""
from
django
import
template
from
django
import
template
register
=
template
.
Library
()
register
=
template
.
Library
()
# pylint: disable=invalid-name
@
register
.
filter
(
name
=
'fieldtype'
)
@
register
.
filter
(
name
=
'fieldtype'
)
def
fieldtype
(
field
):
def
fieldtype
(
field
):
"""
Get the field type for a form field.
:param field: field for which to get the field type
:return: field type
:rtype: str
"""
return
field
.
field
.
widget
.
__class__
.
__name__
return
field
.
field
.
widget
.
__class__
.
__name__
website/thaliawebsite/templatetags/menu.py
View file @
e31fea84
"""Provides a template handler that renders the menu"""
from
django
import
template
from
django
import
template
from
..menus
import
main
from
..menus
import
MAIN_MENU
register
=
template
.
Library
()
register
=
template
.
Library
()
# pylint: disable=invalid-name
@
register
.
inclusion_tag
(
'menu/menu.html'
,
takes_context
=
True
)
@
register
.
inclusion_tag
(
'menu/menu.html'
,
takes_context
=
True
)
def
render_main_menu
(
context
):
def
render_main_menu
(
context
):
return
{
'menu'
:
main
,
'request'
:
context
.
get
(
'request'
)}
"""
Renders the main menu in this place.
Accounts for logged-in status and locale.
"""
return
{
'menu'
:
MAIN_MENU
,
'request'
:
context
.
get
(
'request'
)}
website/thaliawebsite/templatetags/pick_header_image.py
View file @
e31fea84
"""
Get a random header image
"""
import
functools
import
functools
import
os
import
os
import
random
import
random
...
@@ -7,17 +10,18 @@ from django.conf import settings
...
@@ -7,17 +10,18 @@ from django.conf import settings
from
django.contrib.staticfiles
import
finders
from
django.contrib.staticfiles
import
finders
register
=
template
.
Library
()
register
=
template
.
Library
()
# pylint: disable=invalid-name
bannerdir
=
'images/header_banners'
BANNERDIR
=
'images/header_banners'
@
functools
.
lru_cache
()
@
functools
.
lru_cache
()
def
_banners
():
def
_banners
():
imgdir
=
finders
.
find
(
bannerdir
)
"""Get the available banners"""
imgdir
=
finders
.
find
(
BANNERDIR
)
return
[
pic
for
pic
in
os
.
listdir
(
imgdir
)
if
pic
.
endswith
(
'.jpg'
)]
return
[
pic
for
pic
in
os
.
listdir
(
imgdir
)
if
pic
.
endswith
(
'.jpg'
)]
@
register
.
simple_tag
@
register
.
simple_tag
def
pick_header_image
():
def
pick_header_image
():
"""Renders a random header image"""
"""Renders a random header image"""
return
settings
.
STATIC_URL
+
bannerdir
+
'/'
+
random
.
choice
(
_banners
())
return
settings
.
STATIC_URL
+
BANNERDIR
+
'/'
+
random
.
choice
(
_banners
())
website/thaliawebsite/tests.py
View file @
e31fea84
"""Tests for things provided by this module"""
import
doctest
import
doctest
from
django.contrib.auth
import
get_user_model
from
django.contrib.auth
import
get_user_model
...
@@ -6,14 +7,16 @@ from django.test import TestCase, override_settings
...
@@ -6,14 +7,16 @@ from django.test import TestCase, override_settings
from
members.models
import
Profile
from
members.models
import
Profile
from
thaliawebsite.templatetags
import
bleach_tags
from
thaliawebsite.templatetags
import
bleach_tags
from
thaliawebsite
import
sitemaps
def
load_tests
(
loader
,
tests
,
ignore
):
def
load_tests
(
_
loader
,
tests
,
_
ignore
):
"""
"""
Load all tests in this module
Load all tests in this module
"""
"""
# Adds the doctests in bleach_tags
# Adds the doctests in bleach_tags
tests
.
addTests
(
doctest
.
DocTestSuite
(
bleach_tags
))
tests
.
addTests
(
doctest
.
DocTestSuite
(
bleach_tags
))
tests
.
addTests
(
doctest
.
DocTestSuite
(
sitemaps
))
return
tests
return
tests
...
@@ -29,12 +32,14 @@ class WikiLoginTestCase(TestCase):
...
@@ -29,12 +32,14 @@ class WikiLoginTestCase(TestCase):
email
=
'foo@bar.com'
,
email
=
'foo@bar.com'
,
password
=
'top secret'
)
password
=
'top secret'
)
def
test_login_GET_denied
(
self
):
def
test_login_get_request_denied
(
self
):
"""GET shouldn't work for the wiki API"""
response
=
self
.
client
.
get
(
'/api/wikilogin'
)
response
=
self
.
client
.
get
(
'/api/wikilogin'
)
self
.
assertEqual
(
response
.
status_code
,
405
)
self
.
assertEqual
(
response
.
status_code
,
405
)
@
override_settings
(
WIKI_API_KEY
=
'wrongkey'
)
@
override_settings
(
WIKI_API_KEY
=
'wrongkey'
)
def
test_login_wrong_apikey
(
self
):
def
test_login_wrong_apikey
(
self
):
"""API key should be verified"""
response
=
self
.
client
.
post
(
'/api/wikilogin'
,
response
=
self
.
client
.
post
(
'/api/wikilogin'
,
{
'apikey'
:
'rightkey'
,
{
'apikey'
:
'rightkey'
,
'username'
:
'testuser'
,
'username'
:
'testuser'
,
...
@@ -44,6 +49,7 @@ class WikiLoginTestCase(TestCase):
...
@@ -44,6 +49,7 @@ class WikiLoginTestCase(TestCase):
@
override_settings
(
WIKI_API_KEY
=
'key'
)
@
override_settings
(
WIKI_API_KEY
=
'key'
)
def
test_login
(
self
):
def
test_login
(
self
):
"""Test a correct log in attempt"""
response
=
self
.
client
.
post
(
'/api/wikilogin'
,
response
=
self
.
client
.
post
(
'/api/wikilogin'
,
{
'apikey'
:
'key'
,
{
'apikey'
:
'key'
,
'user'
:
'testuser'
,
'user'
:
'testuser'
,
...
@@ -59,6 +65,7 @@ class WikiLoginTestCase(TestCase):
...
@@ -59,6 +65,7 @@ class WikiLoginTestCase(TestCase):
@
override_settings
(
WIKI_API_KEY
=
'key'
)
@
override_settings
(
WIKI_API_KEY
=
'key'
)
def
test_login_with_profile
(
self
):
def
test_login_with_profile
(
self
):
"""A user that has a profile should be able to log in"""
Profile
.
objects
.
create
(
Profile
.
objects
.
create
(
user
=
self
.
user
,
user
=
self
.
user
,
student_number
=
's1234567'
student_number
=
's1234567'
...
@@ -79,6 +86,7 @@ class WikiLoginTestCase(TestCase):
...
@@ -79,6 +86,7 @@ class WikiLoginTestCase(TestCase):
@
override_settings
(
WIKI_API_KEY
=
'key'
)
@
override_settings
(
WIKI_API_KEY
=
'key'
)
def
test_board_permission
(
self
):
def
test_board_permission
(
self
):
"""The board should get access to the board wiki"""
self
.
user
.
user_permissions
.
add
(
self
.
user
.
user_permissions
.
add
(
Permission
.
objects
.
get
(
codename
=
'board_wiki'
))
Permission
.
objects
.
get
(
codename
=
'board_wiki'
))
response
=
self
.
client
.
post
(
'/api/wikilogin'
,
response
=
self
.
client
.
post
(
'/api/wikilogin'
,
...
@@ -95,6 +103,7 @@ class WikiLoginTestCase(TestCase):
...
@@ -95,6 +103,7 @@ class WikiLoginTestCase(TestCase):
@
override_settings
(
WIKI_API_KEY
=
'key'
)
@
override_settings
(
WIKI_API_KEY
=
'key'
)
def
test_wrongargs
(
self
):
def
test_wrongargs
(
self
):
"""Check that the arguments are correct"""
response
=
self
.
client
.
post
(
'/api/wikilogin'
,
response
=
self
.
client
.
post
(
'/api/wikilogin'
,
{
'apikey'
:
'key'
,
{
'apikey'
:
'key'
,
'username'
:
'testuser'
,
'username'
:
'testuser'
,
...
@@ -110,6 +119,7 @@ class WikiLoginTestCase(TestCase):
...
@@ -110,6 +119,7 @@ class WikiLoginTestCase(TestCase):
@
override_settings
(
WIKI_API_KEY
=
'key'
)
@
override_settings
(
WIKI_API_KEY
=
'key'
)
def
test_login_wrong_password
(
self
):
def
test_login_wrong_password
(
self
):
"""Check that the password is actually checked"""
response
=
self
.
client
.
post
(
'/api/wikilogin'
,
response
=
self
.
client
.
post
(
'/api/wikilogin'
,
{
'apikey'
:
'key'
,
{
'apikey'
:
'key'
,
'user'
:
'testuser'
,
'user'
:
'testuser'
,
...
...
website/thaliawebsite/urls.py
View file @
e31fea84
...
@@ -40,30 +40,34 @@ from django.views.generic import TemplateView
...
@@ -40,30 +40,34 @@ from django.views.generic import TemplateView
from
django.views.i18n
import
JavaScriptCatalog
from
django.views.i18n
import
JavaScriptCatalog
import
members
import
members
from
members.sitemaps
import
sitemap
as
members_sitemap