Add 'Tip of the Day' app to display helpful messages to users
This commit is contained in:
parent
987d631a45
commit
b3a832a420
12 changed files with 139 additions and 2 deletions
|
@ -56,6 +56,7 @@ INSTALLED_APPS = [
|
||||||
'accounts',
|
'accounts',
|
||||||
'resume',
|
'resume',
|
||||||
'simple_ga',
|
'simple_ga',
|
||||||
|
'totd',
|
||||||
]
|
]
|
||||||
|
|
||||||
LOGIN_URL = 'login'
|
LOGIN_URL = 'login'
|
||||||
|
@ -105,6 +106,7 @@ TEMPLATES = [
|
||||||
'social_django.context_processors.login_redirect',
|
'social_django.context_processors.login_redirect',
|
||||||
'django_settings_export.settings_export',
|
'django_settings_export.settings_export',
|
||||||
'simple_ga.context_processors.events',
|
'simple_ga.context_processors.events',
|
||||||
|
'totd.context_processors.tips',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -204,6 +206,7 @@ SETTINGS_EXPORT = [
|
||||||
# Make django messages framework use Bootstrap's alert style classes
|
# Make django messages framework use Bootstrap's alert style classes
|
||||||
from django.contrib.messages import constants as messages
|
from django.contrib.messages import constants as messages
|
||||||
MESSAGE_TAGS = {
|
MESSAGE_TAGS = {
|
||||||
|
messages.DEBUG: 'alert-debug',
|
||||||
messages.INFO: 'alert-info',
|
messages.INFO: 'alert-info',
|
||||||
messages.SUCCESS: 'alert-success',
|
messages.SUCCESS: 'alert-success',
|
||||||
messages.WARNING: 'alert-warning',
|
messages.WARNING: 'alert-warning',
|
||||||
|
|
|
@ -121,6 +121,12 @@ ul.errorlist li {
|
||||||
text-shadow: 2px 2px #444;
|
text-shadow: 2px 2px #444;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.alert-debug {
|
||||||
|
color: #383d41;
|
||||||
|
background-color: #e2e3e5;
|
||||||
|
border-color: #d6d8db;
|
||||||
|
}
|
||||||
|
|
||||||
.btn-default {
|
.btn-default {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
background-color: #848484;
|
background-color: #848484;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{% load static %}
|
{% load static markup %}
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
|
@ -90,7 +90,13 @@
|
||||||
|
|
||||||
<main role="main" class="container">
|
<main role="main" class="container">
|
||||||
|
|
||||||
{% if messages %}
|
{% if tip %}
|
||||||
|
<div class="alerts">
|
||||||
|
<div class="alert {{ tip.tags }}"><strong>Tip: </strong>{{ tip.text|safe }}</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if messages %}
|
||||||
<div class="alerts">
|
<div class="alerts">
|
||||||
{% for message in messages %}
|
{% for message in messages %}
|
||||||
<div class="alert{% if message.tags %} {{ message.tags }}{% endif %}">{{ message }}</div>
|
<div class="alert{% if message.tags %} {{ message.tags }}{% endif %}">{{ message }}</div>
|
||||||
|
|
0
totd/__init__.py
Normal file
0
totd/__init__.py
Normal file
32
totd/admin.py
Normal file
32
totd/admin.py
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
from django.contrib import admin
|
||||||
|
from django.urls.resolvers import get_resolver
|
||||||
|
from django import forms
|
||||||
|
|
||||||
|
from .models import Tip
|
||||||
|
|
||||||
|
def url_choices():
|
||||||
|
choices = [('', '-- All Pages --')]
|
||||||
|
for entry in get_resolver(None).url_patterns:
|
||||||
|
if entry.pattern.name:
|
||||||
|
choices.append((entry.pattern.name, entry.pattern.name))
|
||||||
|
return choices
|
||||||
|
|
||||||
|
# Register your models here.
|
||||||
|
class TipForm(forms.ModelForm):
|
||||||
|
class Meta:
|
||||||
|
model = Tip
|
||||||
|
fields = '__all__'
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
self.fields['view'].widget = forms.Select(choices=url_choices())
|
||||||
|
|
||||||
|
class TipAdmin(admin.ModelAdmin):
|
||||||
|
#raw_id_fields = ('seen_by',)
|
||||||
|
list_filter =('level', 'view')
|
||||||
|
list_display = ('name', 'level', 'view', 'run_start', 'run_end')
|
||||||
|
search_fields = ('name', 'view')
|
||||||
|
form = TipForm
|
||||||
|
|
||||||
|
|
||||||
|
admin.site.register(Tip, TipAdmin)
|
5
totd/apps.py
Normal file
5
totd/apps.py
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class TotdConfig(AppConfig):
|
||||||
|
name = 'totd'
|
25
totd/context_processors.py
Normal file
25
totd/context_processors.py
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
from django.db.models import Q
|
||||||
|
from .models import Tip
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
def tips(request):
|
||||||
|
"""
|
||||||
|
Adds a list of tips for the current request
|
||||||
|
"""
|
||||||
|
if not request.user.is_authenticated:
|
||||||
|
return {}
|
||||||
|
|
||||||
|
#import pdb; pdb.set_trace()
|
||||||
|
|
||||||
|
tips = Tip.objects.filter(run_start__lte=datetime.datetime.now())
|
||||||
|
tips = tips.filter(Q(run_end__isnull=True) | Q(run_end__gte=datetime.datetime.now()))
|
||||||
|
tips = tips.filter(Q(view='') | Q(view=request.resolver_match.url_name)).exclude(seen_by=request.user)
|
||||||
|
if len(tips) > 0:
|
||||||
|
tips[0].seen_by.add(request.user)
|
||||||
|
|
||||||
|
return {
|
||||||
|
'tip': tips[0],
|
||||||
|
}
|
||||||
|
|
||||||
|
return {}
|
32
totd/migrations/0001_Initial_models.py
Normal file
32
totd/migrations/0001_Initial_models.py
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
# Generated by Django 2.0 on 2018-09-22 05:16
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.utils.timezone
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('sites', '0002_alter_domain_unique'),
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Tip',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('name', models.CharField(max_length=128)),
|
||||||
|
('text', models.TextField()),
|
||||||
|
('level', models.SmallIntegerField(choices=[(10, 'debug'), (20, 'info'), (25, 'success'), (30, 'warning'), (40, 'error')], default=20)),
|
||||||
|
('run_start', models.DateTimeField(default=django.utils.timezone.now)),
|
||||||
|
('run_end', models.DateTimeField(blank=True, null=True)),
|
||||||
|
('view', models.CharField(blank=True, max_length=256, null=True)),
|
||||||
|
('seen_by', models.ManyToManyField(blank=True, related_name='seen_tips', to=settings.AUTH_USER_MODEL)),
|
||||||
|
('sites', models.ManyToManyField(to='sites.Site')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
0
totd/migrations/__init__.py
Normal file
0
totd/migrations/__init__.py
Normal file
22
totd/models.py
Normal file
22
totd/models.py
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
from django.db import models
|
||||||
|
from django.contrib.sites.models import Site
|
||||||
|
from django.contrib.messages.constants import DEFAULT_TAGS, INFO
|
||||||
|
from django.conf import settings
|
||||||
|
from django.utils import timezone
|
||||||
|
|
||||||
|
# Create your models here.
|
||||||
|
class Tip(models.Model):
|
||||||
|
name = models.CharField(max_length=128, null=False, blank=False)
|
||||||
|
text = models.TextField()
|
||||||
|
level = models.SmallIntegerField(choices=DEFAULT_TAGS.items(), default=INFO)
|
||||||
|
|
||||||
|
run_start = models.DateTimeField(default=timezone.now)
|
||||||
|
run_end = models.DateTimeField(null=True, blank=True)
|
||||||
|
|
||||||
|
view = models.CharField(max_length=256, blank=True, null=True)
|
||||||
|
sites = models.ManyToManyField(Site)
|
||||||
|
|
||||||
|
seen_by = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='seen_tips', blank=True)
|
||||||
|
|
||||||
|
def tags(self):
|
||||||
|
return settings.MESSAGE_TAGS[self.level]
|
3
totd/tests.py
Normal file
3
totd/tests.py
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
# Create your tests here.
|
3
totd/views.py
Normal file
3
totd/views.py
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
from django.shortcuts import render
|
||||||
|
|
||||||
|
# Create your views here.
|
Loading…
Reference in a new issue