joeni

Major additions to roster system and login

I've added a lot of changes to the roster system (that will be finished tomorrow). I've implemented the template for a large part, and written the view behind it as well.
In the current state, it's going to be hard to make it all work well with just the Django template language, largely because of the way how I have to work reversed in HTML tables. So I've decided to prepare the rows up front, and then print them in the table directly. This makes the roster view pretty large, but that can be refactored in the future.
Other small changes include working on the login screen and URL handling, changing the settings to be more forgiving for debugging, and hiding the header for now, as it got annoyingly in the way

Author
Maarten 'Vngngdn' Vangeneugden
Date
Feb. 1, 2018, 7:28 p.m.
Hash
09579b7d3616c73134d6fe268f106bb32513d21b
Parent
bf3254b908dee6e18e21bccce1b5d832e87d871e
Modified files
administration/templates/administration/index.djhtml
administration/templates/administration/login.djhtml
administration/templates/administration/nav.djhtml
administration/templates/administration/roster.djhtml
administration/urls.py
administration/views.py
joeni/settings.py
static/css/header.css

administration/templates/administration/index.djhtml

0 additions and 1 deletion.

View changes Hide changes
1
1
{% load i18n %}
2
2
{% load humanize %}
3
3
{% load crispy_forms_tags %}
4
-
{% load joeni_org %}
5
4
6
5
{% block title %}
7
6
    {% trans "Administration" %} | ◀ Joeni /▶
8
7
{% endblock %}
9
8
10
9
{% block main %}
11
10
    {% include "administration/nav.djhtml" %}
12
11
    <h1>{% trans "Administration" %}</h1>
13
12
    <p>
14
13
        {% blocktrans %}
15
14
            Welcome to the administration website of Hasselt University. Here,
16
15
            you can find all links related to the university's services,
17
16
            events, messages, and so on.
18
17
        {% endblocktrans %}
19
18
    </p>
20
19
21
20
    <h2>{% trans "Education department bulletin board" %}</h2>
22
21
    {% for message in education_dept_messages %}
23
22
        <h3>{{message.title}}</h3>
24
23
        <time datetime="{{ message.date|date:'Y-m-d' }}">
25
24
            {{ message.date|naturaltime }}
26
25
        </time>
27
26
        <p>{{message.text|org}}</p>
28
27
    {% empty %}
29
28
        <p>{% trans "There are no messages available." %}</p>
30
29
    {% endfor %}
31
30
32
31
    <h2>{% trans "Important telephone numbers and contact services" %}</h2>
33
32
    <dl>
34
33
        <dt>{% trans "Student secretary during working hours" %}</dt>
35
34
        <dd><a href="tel:+3211268100">(+32)11 26 81 00</a></dd>
36
35
        <dt>{% trans "Student police | District office" %}</dt>
37
36
        <dd><a href="tel:+3211268115">(+32)11 26 81 15</a></dd>
38
37
        <dt>{% trans "Student police | District service" %}</dt>
39
38
        <dd><a href="tel:+3211323300">(+32)11 32 33 00</a></dd>
40
39
    </dl>
41
40
    {% comment %}
42
41
        Psychosociale opvang binnen de kantooruren
43
42
        Studentenpsycholoog:studentenpsycholoog@uhasselt.be - tel.:011 26 90 48
44
43
        Maatschappelijk assistent: Liesbeth Huber
45
44
        Logistieke vragen buiten de kantooruren
46
45
        Dienst MAT Diepenbeek: 0475 94 30 02
47
46
        Dienst MAT Hasselt: 0493 59 38 33
48
47
        Studentenpolitie
49
48
        Wijkkantoor: 011 26 81 15
50
49
        Wijkdienst: 011 32 33 00
51
50
        0499 59 57 28
52
51
        Tele-Onthaal (24u/24u)
53
52
        106 
54
53
    #TODO
55
54
    {% endcomment %}
56
55
57
56
{% endblock main %}
58
57

administration/templates/administration/login.djhtml

1 addition and 0 deletions.

View changes Hide changes
1
1
{% load i18n %}
2
2
3
3
{% block title %}
4
4
    {% trans "Log in | ◀ Joeni /▶" %}
5
5
{% endblock %}
6
6
7
7
{% block main %}
8
8
    <h1>{% trans "Authenticate with Joeni" %}</h1>
9
9
    <p>
10
10
        {% blocktrans %}
11
11
            This page is only visible for students and personnel of Hasselt University.
12
12
            Please authenticate yourself with Joeni in order to continue.
13
13
        {% endblocktrans %}
14
14
    </p>
15
15
16
16
<style>
17
17
 /* label color */
18
18
   .input-field label {
19
19
     color: #9e9e9e;
20
20
   }
21
21
   /* label focus color */
22
22
   .input-field input[type=password]:focus + label {
23
23
     color: #ffc107;
24
24
   }
25
25
   /* label underline focus color */
26
26
   .input-field input[type=password]:focus {
27
27
     border-bottom: 1px solid #ffc107;
28
28
     box-shadow: 0 1px 0 0 #ffc107;
29
29
   }
30
30
   .input-field input[type=text]:focus + label {
31
31
     color: #ffc107;
32
32
   }
33
33
   /* label underline focus color */
34
34
   .input-field input[type=text]:focus {
35
35
     border-bottom: 1px solid #ffc107;
36
36
     box-shadow: 0 1px 0 0 #ffc107;
37
37
   }
38
38
   /* icon prefix focus color */
39
39
   .input-field .prefix.active {
40
40
     color: #ffc107;
41
41
   }
42
42
</style>
43
43
<form action="{% url 'administration-login' %}" method="post">
44
44
    {% csrf_token %} {# This is necessary for forms, CSRF protection. #}
45
45
    <label for="name">{% trans "Name" %}</label>
+
46
    <label for="name">{% trans "Name" %}</label>
46
47
    <input id="name" name="name" type="text" class="validate" require />
47
48
    <br />
48
49
    <label for="pass">{% trans "Passphrase" %}</label>
49
50
    <input id="pass" name="pass" type="password" require />
50
51
    <input type="submit" value="{% trans "Log in" %}" />
51
52
</form>
52
53
{% endblock main %}
53
54

administration/templates/administration/nav.djhtml

1 addition and 1 deletion.

View changes Hide changes
1
1
{% load i18n %}
2
2
<nav>
3
3
    <a href="{% url 'administration-settings' %}">{% trans "Personal settings" %}</a>
4
4
    <a href="{% url 'administration-curriculum' %}">{% trans "Curricula" %}</a>
5
5
    <a href="{% url 'administration-results' %}">{% trans "Course results" %}</a>
6
-
    <a href="{% url 'administration-forms' %}">{% trans "Forms" %}</a>
+
6
    <a href="{% url 'administration-forms' %}">{% trans "Forms" %}</a>
7
7
    <a href="{% url 'administration-rooms' %}">{% trans "Rooms" %}</a>
8
8
    <a href="{% url 'administration-roster' %}">{% trans "Personal Roster" %}</a>
9
9
</nav>
10
10

administration/templates/administration/roster.djhtml

32 additions and 1 deletion.

View changes Hide changes
1
1
{% load i18n %}
+
2
{# "silent" blocks the cycle operator from printing the cycler, and in subsequent calls #}
+
3
{% load i18n %}
2
4
3
5
{% block title %}
4
6
    {% trans "Roster | ◀ Joeni /▶" %}
5
7
{% endblock %}
6
8
7
9
{% block main %}
8
10
    {% include "administration/nav.djhtml" %}
9
11
    <h1>{% trans "" %}</h1>
10
-
{% endblock main %}
+
12
    <p>
+
13
        {% trans "Personal roster from" %} {{ begin|date }} {% trans "to" %} {{ end|date }}
+
14
    </p>
+
15
    <table>
+
16
        <th>
+
17
            <td></td> {# Empty row for hours #}
+
18
            {% for day in days %}
+
19
                <td>{{ day|date:"l (d/m)" }}</td>
+
20
            {% endfor %}
+
21
        </th>
+
22
        {% for time, events in time_blocks %}
+
23
            <tr>
+
24
                {% if hour == "hour" %}
+
25
                    <td>{{ time }}</td>
+
26
                {% else %}
+
27
                    <td></td>
+
28
                {% endif %}
+
29
                {% cycle hour %}
+
30
                <td>{{ time }}</td>
+
31
                <!--<td rowspan="5">AI</td>
+
32
                <td>Dinsdag</td>
+
33
                <td>Dinsdag</td>
+
34
                <td>Woensdag</td>
+
35
                <td>Dondeddag</td>
+
36
                <td>Vdijdag</td>
+
37
                <td>Zaterdag</td>-->
+
38
            </tr>
+
39
        {% endfor %}
+
40
    </table>
+
41
{% endblock main %}
11
42

administration/urls.py

6 additions and 4 deletions.

View changes Hide changes
1
-
from django.contrib.auth import views as auth_views
+
1
from django.contrib.auth import views as auth_views
2
2
from . import views
3
3
from django.utils.translation import gettext_lazy as _
4
4
5
5
urlpatterns = ([
6
6
    path('', views.index, name='administration-index'),
7
7
    path(_('pre-registration'), views.pre_registration, name='administration-pre-registration'),
8
8
    path(_('settings'), views.settings, name='administration-settings'),
9
9
    path(_('curriculum'), views.curriculum, name='administration-curriculum'),
10
10
    path(_('results'), views.results, name='administration-results'),
11
-
    path(_('results/<slug:course>'), views.result, name='administration-results'),
12
-
    path(_('results/<int:student_id>'), views.result, name='administration-results'),
13
-
    path(_('forms'), views.forms, name='administration-forms'),  # In Dutch: "Attesten"
+
11
    #path(_('results'), views.results, name='administration-results'),
+
12
    #path(_('results/<slug:course>'), views.result, name='administration-results'),
+
13
    #path(_('results/<int:student_id>'), views.result, name='administration-results'),
+
14
    path(_('forms'), views.forms, name='administration-forms'),  # In Dutch: "Attesten"
14
15
    path(_('forms/<str:form>'), views.forms, name='administration-forms'),
15
16
    path(_('rooms'), views.rooms, name='administration-rooms'),
16
17
    path(_('rooms/<str:room>'), views.rooms, name='administration-rooms'),
17
18
    path(_('rooms/reservate'), views.room_reservate, name='administration-room-reservate'),
18
19
    path(_('roster'), views.roster, name='administration-roster'),
19
20
    path(_('jobs'), views.jobs, name='administration-jobs'),
+
21
    path(_('jobs'), views.jobs, name='administration-jobs'),
20
22
    path(_('bulletin-board'), views.bulletin_board, name='administration-bulletin-board'),
21
23
22
24
    path('login', views.login, name='administration-login'),
23
25
    ])
24
26

administration/views.py

54 additions and 24 deletions.

View changes Hide changes
1
1
import datetime
+
2
import datetime
2
3
from django.urls import reverse # Why?
3
4
from django.utils.translation import gettext as _
4
5
from .models import *
5
6
from .forms import UserDataForm
6
7
import administration
7
8
from django.contrib.auth.decorators import login_required
8
9
+
10
9
11
@login_required
10
12
def roster(request, begin=None, end=None):
11
13
    """Collects and renders the data that has to be displayed in the roster.
12
14
13
15
    The begin and end date can be specified. Only roster points in that range
14
16
    will be included in the response. If no begin and end are specified, it will
15
17
    take the current week as begin and end point. If it's
16
18
    weekend, it will take next week."""
17
19
18
20
    template = "administration/roster.djhtml"
+
21
    context = dict()
+
22
    template = "administration/roster.djhtml"
19
23
20
24
    if begin is None or end is None:
21
25
        today = datetime.date.today()
22
26
        if today.isoweekday() in {6,7}:  # Weekend
23
27
            begin = today + datetime.timedelta(days=8-today.isoweekday())
24
28
            end = today + datetime.timedelta(days=13-today.isoweekday())
25
29
        else:  # Same week
26
30
            begin = today - datetime.timedelta(days=today.weekday())
27
31
            end = today + datetime.timedelta(days=5-today.isoweekday())
28
32
+
33
    context['end'] = end
+
34
29
35
+
36
    while (end-days[-1]).days != 0:
+
37
        # Human translation: Keep adding days until the last day in the array of
+
38
        # days is the same day as the last day the user wants to see the roster for.
+
39
        days.append(days[-1] + datetime.timedelta(days=1))
+
40
    context['days'] = days
+
41
30
42
    course_events = CourseEvent.objects.filter(begin_time__gte=begin).filter(end_time__lte=end)
+
43
    course_events = CourseEvent.objects.filter(begin_time__gte=begin).filter(end_time__lte=end)
31
44
    university_events = UniversityEvent.objects.filter(begin_time__gte=begin).filter(end_time__lte=end)
32
45
    study_events = StudyEvent.objects.filter(begin_time__gte=begin).filter(end_time__lte=end)
33
46
    events = Event.objects.filter(begin_time__gte=begin).filter(end_time__lte=end)
34
47
35
48
    return render(request, template, context)
+
49
    time_blocks = []
+
50
    for i in range(8, 20):
+
51
        time_block = str(i)
+
52
        for j in range(0, 60, 15):
+
53
            if j == 0:
+
54
                time_blocks.append([time_block + ":00",""])
+
55
                continue
+
56
            time_blocks.append([time_block + ":" + str(j), ""])
+
57
    context['time_blocks'] = time_blocks
+
58
+
59
    # Preparing events for the template
+
60
    c_es = []
+
61
    for course_event in course_events:
+
62
        duration = course_event.end - course_event.begin
+
63
        quarters = duration.minutes // 15
+
64
        course_item = str(
+
65
              "<td style='background-color:'"+course_event.course.course.color+";' rowspan='"
+
66
            + str(quarters) + "'>"
+
67
            + "<a href=" + reverse("courses-course-index", args="")+"> "  # FIXME so that this links to the course's index page
+
68
            + str(course_event.course)
+
69
            + "<br />"
+
70
            + str(course_event.docent)
+
71
            + "<br />"
+
72
            + str(course_event.room) + " (" + str(course_event.subject) + ")</a></td>")
+
73
+
74
+
75
+
76
+
77
    return render(request, template, context)
36
78
    # TODO Finish!
37
79
38
80
def index(request):
39
81
    template = "administration/index.djhtml"
40
82
    context = {}
41
83
    return render(request, template, context)
42
84
43
85
    pass
44
86
45
87
def pre_registration(request):
46
88
    user_data_form = UserDataForm()
47
89
    template = "administration/pre_registration.djhtml"
48
90
    context = dict()
49
91
50
92
    if request.method == 'POST':
51
93
        user_data_form = UserDataForm(request.POST)
52
94
        context['user_data_form'] = user_data_form
53
95
        if user_data_form.is_valid():
54
96
            user_data_form.save()
55
97
            context['messsage'] = _("Your registration has been completed. You will receive an e-mail shortly.")
56
98
        else:
57
99
            context['messsage'] = _("The data you supplied had errors. Please review your submission.")
58
100
    else:
59
101
        context['user_data_form'] = UserDataForm(instance = user_data)
60
102
61
103
    return render(request, template, context)
62
104
    pass
63
105
64
106
@login_required
65
107
def settings(request):
66
108
    user_data = UserData.objects.get(user=request.user)
67
109
    user_data_form = UserDataForm(instance = user_data)
68
110
    template = "administration/settings.djhtml"
69
111
    context = dict()
70
112
71
113
    if request.method == 'POST':
72
114
        user_data_form = UserDataForm(request.POST, instance = user_data)
73
115
        context['user_data_form'] = user_data_form
74
116
        if user_data_form.is_valid():
75
117
            user_data_form.save()
76
118
            context['messsage'] = _("Your settings were successfully updated.")
77
119
        else:
78
120
            context['messsage'] = _("The data you supplied had errors. Please review your submission.")
79
121
    else:
80
122
        context['user_data_form'] = UserDataForm(instance = user_data)
81
123
82
124
    return render(request, template, context)
83
125
84
126
@login_required
85
127
def bulletin_board(request):
86
128
    context = dict()
87
129
    context['exam_commission_decisions'] = ExamCommissionDecision.objects.filter(user=request.user)
88
130
    context['education_department_messages'] = ExamCommissionDecision.objects.filter(user=request.user)
89
131
    template = "administration/bulletin_board.djhtml"
90
132
    return render(request, template, context)
91
133
92
134
def jobs(request):
93
135
    context = dict()
94
136
    template = "administration/jobs.djhtml"
95
137
    #@context['decisions'] = ExamCommissionDecision.objects.filter(user=request.user)
96
138
    return render(request, template, context)
97
139
98
140
99
141
def curriculum(request):
100
142
    return render(request, template, context)
101
143
102
144
def result(request):
103
145
    return render(request, template, context)
104
146
105
147
@login_required
106
148
def results(request):
107
149
    results = CourseResult.objects.filter(student=request.user)
108
150
    template = "administration/results.djhtml"
109
151
    # TODO
110
152
    return render(request, template, context)
111
153
112
154
def forms(request):
113
155
    return render(request, template, context)
114
156
115
157
def rooms(request):
116
158
    template = "administration/rooms.djhtml"
117
159
    return render(request, template, context)
118
160
119
161
def room_reservate(request):
120
162
    return render(request, template, context)
121
163
122
164
def login(request):
123
165
    if request.method == "POST":
+
166
    if request.method == "POST":
124
167
        name = request.POST['name']
125
168
        passphrase = request.POST['password']
126
-
        user = authenticate(username=name, password=passphrase)
+
169
        user = authenticate(username=name, password=passphrase)
127
170
        if user is not None: # The user was successfully authenticated.
128
-
            login(request, user)
129
-
            # Because of Leen, I now track when and where is logged in:
130
-
            loginRecord = Login()
131
-
            loginRecord.ip = request.META['REMOTE_ADDR']
132
-
            loginRecord.name = name
133
-
            loginRecord.save()
134
-
            return HttpResponseRedirect(reverse('ITdays-index'))
135
-
+
171
            print("YA")
+
172
            return HttpResponseRedirect(request.POST['next'])
+
173
        else: # User credentials were wrong
+
174
            context['next'] = request.POST['next']
+
175
            context['message'] = _("The given credentials were not correct.")
+
176
    else:
+
177
        context['next'] = request.GET.get('next', None)
+
178
        if context['next'] is None:
+
179
            context['next'] = reverse('administration-index')
+
180
136
181
    template = 'administration/login.djhtml'
137
182
138
183
    footer_links = [
139
-
            ["Home", "/"],
140
-
            ["Contact", "mailto:maarten.vangeneugden@student.uhasselt.be"],
141
-
            ]
142
-
143
-
    context = {
144
-
            'materialDesign_color': "deep-purple",
145
-
            'materialDesign_accentColor': "amber",
146
-
            'navbar_title': "Authentication",
147
-
            'navbar_fixed': True,
148
-
            'navbar_backArrow': True,
149
-
            'footer_title': "Quotebook",
150
-
            'footer_description': "Een lijst van citaten uit 2BACH Informatica @ UHasselt.",
151
-
            'footer_links': footer_links,
152
-
            }
153
-
    return render(request, template, context)
154
184

joeni/settings.py

19 additions and 15 deletions.

View changes Hide changes
1
1
Django settings for Joeni project.
2
2
3
3
Generated by 'django-admin startproject' using Django 2.0b1.
4
4
5
5
For more information on this file, see
6
6
https://docs.djangoproject.com/en/dev/topics/settings/
7
7
8
8
For the full list of settings and their values, see
9
9
https://docs.djangoproject.com/en/dev/ref/settings/
10
10
"""
11
11
12
12
import os
13
13
14
14
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
15
15
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
16
16
17
17
18
18
# Quick-start development settings - unsuitable for production
19
19
# See https://docs.djangoproject.com/en/dev/howto/deployment/checklist/
20
20
21
21
# SECURITY WARNING: keep the secret key used in production secret!
22
22
SECRET_KEY = '!2634qc=b*lp0=helzcmvb3+1_wcl!6z@mhzi%p(vg7odq&gfz'
23
23
24
24
# SECURITY WARNING: don't run with debug turned on in production!
25
25
DEBUG = True
26
26
27
27
# Crispy settings
28
28
CRISPY_FAIL_SILENTLY = not DEBUG  # For debugging info for Crispy
29
29
CRISPY_TEMPLATE_PACK = "hasselt-university"
30
30
31
31
32
32
ALLOWED_HOSTS = []
33
33
34
34
35
35
# Application definition
36
36
37
37
INSTALLED_APPS = [
38
38
    'django.contrib.admin',
39
39
    'django.contrib.auth',
40
40
    'django.contrib.contenttypes',
41
41
    'django.contrib.humanize',
42
42
    'django.contrib.sessions',
43
43
    'django.contrib.messages',
44
44
    'django.contrib.staticfiles',
45
45
    'administration',
46
46
    'agora',
47
47
    'courses',
48
48
    'joeni',
49
49
]
50
50
51
51
MIDDLEWARE = [
52
52
    'django.middleware.security.SecurityMiddleware',
53
53
    'django.middleware.locale.LocaleMiddleware',
54
54
    'django.middleware.common.CommonMiddleware',
55
55
    'django.middleware.csrf.CsrfViewMiddleware',
56
56
    'django.contrib.sessions.middleware.SessionMiddleware',
57
57
    'django.contrib.auth.middleware.AuthenticationMiddleware',
58
58
    'django.contrib.sessions.middleware.SessionMiddleware',
59
59
    'django.contrib.messages.middleware.MessageMiddleware',
60
60
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
61
61
    'django.middleware.security.SecurityMiddleware',
62
62
    # Caching middleware
63
63
    'django.middleware.cache.UpdateCacheMiddleware',
64
64
    'django.middleware.common.CommonMiddleware',
65
65
    'django.middleware.cache.FetchFromCacheMiddleware',
66
66
]
67
67
68
68
# Caching settings
69
69
CACHE_MIDDLEWARE_ALIAS = 'default'
70
70
CACHE_MIDDLEWARE_SECONDS = 300
71
71
CACHE_MIDDLEWARE_KEY_PREFIX = ''
72
72
73
73
ROOT_URLCONF = 'joeni.urls'
74
74
75
75
TEMPLATES = [
76
76
    {
77
77
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
78
78
        'DIRS': [],
79
79
        'APP_DIRS': True,
80
80
        'OPTIONS': {
81
81
            'context_processors': [
82
82
                'django.template.context_processors.debug',
83
83
                'django.template.context_processors.request',
84
84
                'django.contrib.auth.context_processors.auth',
85
85
                'django.contrib.messages.context_processors.messages',
86
86
            ],
87
87
        },
88
88
    },
89
89
]
90
90
91
91
#WSGI_APPLICATION = 'joeni.wsgi.application'
92
92
93
93
94
94
# Database
95
95
# https://docs.djangoproject.com/en/dev/ref/settings/#databases
96
96
97
97
DATABASES = {
98
98
    'default': {
99
99
        'ENGINE': 'django.db.backends.sqlite3',
100
100
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
101
101
    }
102
102
}
103
103
104
104
# Page to display when a user needs / wants to log in
105
105
LOGIN_URL = 'administration/login'
106
-
+
106
107
107
# Custom User model
108
108
AUTH_USER_MODEL = 'administration.User'
109
109
110
110
# Password validation
111
111
# https://docs.djangoproject.com/en/dev/ref/settings/#auth-password-validators
112
112
113
113
AUTH_PASSWORD_VALIDATORS = [
114
-
    {
115
-
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
116
-
    },
117
-
    {
118
-
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
119
-
    },
120
-
    {
121
-
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
122
-
    },
123
-
    {
124
-
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
125
-
    },
126
-
]
127
-
+
114
if not DEBUG:
+
115
    # XXX: For testing and easily creating new accounts, I've disabled the
+
116
    # validators to make it easier to work with.
+
117
    AUTH_PASSWORD_VALIDATORS = [
+
118
        {
+
119
            'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
+
120
        },
+
121
        {
+
122
            'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
+
123
        },
+
124
        {
+
125
            'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
+
126
        },
+
127
        {
+
128
            'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
+
129
        },
+
130
    ]
+
131
128
132
CACHES = {
129
133
    'default': {
130
134
        'BACKEND': 'django.core.cache.backends.dummy.DummyCache',
131
135
    }
132
136
}
133
137
134
138
# Internationalization
135
139
# https://docs.djangoproject.com/en/dev/topics/i18n/
136
140
137
141
LANGUAGE_CODE = 'en-us'
138
142
139
143
TIME_ZONE = 'UTC'
140
144
141
145
USE_I18N = True
142
146
143
147
USE_L10N = True
144
148
145
149
USE_TZ = True
146
150
147
151
148
152
# Static files (CSS, JavaScript, Images)
149
153
# https://docs.djangoproject.com/en/dev/howto/static-files/
150
154
151
155
STATICFILES_DIRS = [
152
156
    BASE_DIR + "/static",
153
157
    ]
154
158
#STATIC_ROOT = BASE_DIR + '/static/'
155
159
STATIC_URL = '/static/'
156
160
MEDIA_URL = '/media/'
157
161

static/css/header.css

1 addition and 0 deletions.

View changes Hide changes
1
1
    position: fixed;
2
2
    top: 0;
+
3
    top: 0;
3
4
    background-color: #E73B2B;
4
5
}
5
6
header ul {
6
7
    display: inline;
7
8
}
8
9