@@ -0,0 +1,18 @@ | |||
from channels.routing import ProtocolTypeRouter, URLRouter | |||
from django.urls import re_path | |||
from channels.routing import URLRouter | |||
from channels.http import AsgiHandler | |||
from channels.auth import AuthMiddlewareStack | |||
import django_eventstream | |||
urlpatterns = [ | |||
re_path(r'events/', | |||
AuthMiddlewareStack(URLRouter(django_eventstream.routing.urlpatterns)), | |||
{'channels': ['notice']}), | |||
re_path(r'', AsgiHandler), | |||
] | |||
application = ProtocolTypeRouter({ | |||
'http' : URLRouter(urlpatterns) | |||
}) |
@@ -0,0 +1,130 @@ | |||
""" | |||
Django settings for demoweb project. | |||
Generated by 'django-admin startproject' using Django 2.2.6. | |||
For more information on this file, see | |||
https://docs.djangoproject.com/en/2.2/topics/settings/ | |||
For the full list of settings and their values, see | |||
https://docs.djangoproject.com/en/2.2/ref/settings/ | |||
""" | |||
import os | |||
# Build paths inside the project like this: os.path.join(BASE_DIR, ...) | |||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) | |||
# Quick-start development settings - unsuitable for production | |||
# See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/ | |||
# SECURITY WARNING: keep the secret key used in production secret! | |||
SECRET_KEY = '8f$z8o$#psi(4)hsn&jk7^6kyj*tvzpsc!3&uajy^e$og3#z!3' | |||
# SECURITY WARNING: don't run with debug turned on in production! | |||
DEBUG = True | |||
ALLOWED_HOSTS = [] | |||
# Application definition | |||
INSTALLED_APPS = [ | |||
'rest_framework', | |||
'django.contrib.admin', | |||
'django.contrib.auth', | |||
'django.contrib.contenttypes', | |||
'django.contrib.sessions', | |||
'django.contrib.messages', | |||
'django.contrib.staticfiles', | |||
'posts.apps.PostsConfig', | |||
'channels', | |||
'django_eventstream', | |||
] | |||
MIDDLEWARE = [ | |||
'django.middleware.security.SecurityMiddleware', | |||
'django.contrib.sessions.middleware.SessionMiddleware', | |||
'django.middleware.common.CommonMiddleware', | |||
'django.middleware.csrf.CsrfViewMiddleware', | |||
'django.contrib.auth.middleware.AuthenticationMiddleware', | |||
'django.contrib.messages.middleware.MessageMiddleware', | |||
'django.middleware.clickjacking.XFrameOptionsMiddleware', | |||
'django_grip.GripMiddleware', | |||
'django.middleware.security.SecurityMiddleware', | |||
] | |||
ROOT_URLCONF = 'demoweb.urls' | |||
TEMPLATES = [ | |||
{ | |||
'BACKEND': 'django.template.backends.django.DjangoTemplates', | |||
'DIRS': [os.path.join(BASE_DIR, 'templates')] | |||
, | |||
'APP_DIRS': True, | |||
'OPTIONS': { | |||
'context_processors': [ | |||
'django.template.context_processors.debug', | |||
'django.template.context_processors.request', | |||
'django.contrib.auth.context_processors.auth', | |||
'django.contrib.messages.context_processors.messages', | |||
], | |||
}, | |||
}, | |||
] | |||
WSGI_APPLICATION = 'demoweb.wsgi.application' | |||
ASGI_APPLICATION = 'demoweb.routing.application' | |||
# Database | |||
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases | |||
DATABASES = { | |||
'default': { | |||
'ENGINE': 'django.db.backends.sqlite3', | |||
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), | |||
} | |||
} | |||
# Password validation | |||
# https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators | |||
AUTH_PASSWORD_VALIDATORS = [ | |||
{ | |||
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', | |||
}, | |||
{ | |||
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', | |||
}, | |||
{ | |||
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', | |||
}, | |||
{ | |||
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', | |||
}, | |||
] | |||
# Internationalization | |||
# https://docs.djangoproject.com/en/2.2/topics/i18n/ | |||
LANGUAGE_CODE = 'de-de' | |||
TIME_ZONE = 'Europe/Berlin' | |||
USE_I18N = True | |||
USE_L10N = True | |||
USE_TZ = True | |||
# Static files (CSS, JavaScript, Images) | |||
# https://docs.djangoproject.com/en/2.2/howto/static-files/ | |||
STATIC_URL = '/static/' |
@@ -0,0 +1,27 @@ | |||
"""demoweb URL Configuration | |||
The `urlpatterns` list routes URLs to views. For more information please see: | |||
https://docs.djangoproject.com/en/2.2/topics/http/urls/ | |||
Examples: | |||
Function views | |||
1. Add an import: from my_app import views | |||
2. Add a URL to urlpatterns: path('', views.home, name='home') | |||
Class-based views | |||
1. Add an import: from other_app.views import Home | |||
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') | |||
Including another URLconf | |||
1. Import the include() function: from django.urls import include, path | |||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) | |||
""" | |||
from django.contrib import admin | |||
from django.urls import path, include | |||
from posts import views | |||
import posts.views | |||
urlpatterns = [ | |||
path('', posts.views.index), | |||
path('posts/', include('posts.urls')), | |||
path('admin/', admin.site.urls), | |||
path('new/', views.new, name='new') | |||
] |
@@ -0,0 +1,16 @@ | |||
""" | |||
WSGI config for demoweb project. | |||
It exposes the WSGI callable as a module-level variable named ``application``. | |||
For more information on this file, see | |||
https://docs.djangoproject.com/en/2.2/howto/deployment/wsgi/ | |||
""" | |||
import os | |||
from django.core.wsgi import get_wsgi_application | |||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'demoweb.settings') | |||
application = get_wsgi_application() |
@@ -0,0 +1,3 @@ | |||
from django.contrib import admin | |||
# Register your models here. |
@@ -0,0 +1,5 @@ | |||
from django.apps import AppConfig | |||
class PostsConfig(AppConfig): | |||
name = 'posts' |
@@ -0,0 +1,8 @@ | |||
from django.db import models | |||
# Create your models here. | |||
class Notice(models.Model): | |||
notice_title = models.CharField(max_length=80) | |||
notice_text = models.CharField(max_length=400) | |||
pub_start = models.DateTimeField() | |||
pub_end = models.DateTimeField() |
@@ -0,0 +1,3 @@ | |||
from django.test import TestCase | |||
# Create your tests here. |
@@ -0,0 +1,89 @@ | |||
from django.shortcuts import render, redirect | |||
from django.http import HttpResponse, JsonResponse | |||
from .models import Notice | |||
from django.utils import timezone | |||
import logging | |||
from .forms import NoticeForm | |||
from .serializers import NoticeSerializer | |||
from rest_framework.parsers import JSONParser | |||
from django.views.decorators.csrf import csrf_exempt | |||
from django_eventstream import send_event | |||
logger = None | |||
# Create your views here. | |||
def home(request): | |||
return HttpResponse('Es gibt nichts hier.... bye bye') | |||
def initLogger(): | |||
global logger | |||
if logger == None: | |||
logger = logging.getLogger('django.db.backends') | |||
logger.setLevel(logging.DEBUG) | |||
logger.addHandler(logging.StreamHandler()) | |||
def index(request): | |||
initLogger() | |||
notices = Notice.objects.all() | |||
notices = notices.filter(pub_start__lte=timezone.now() ) | |||
notices = notices.filter(pub_end__gte=timezone.now()) | |||
context = { "notices" : notices } | |||
return render(request, 'posts/index.html', context) | |||
def new(request): | |||
if request.method == "POST": | |||
form = NoticeForm(request.POST) | |||
if form.is_valid(): | |||
newNotice = Notice(notice_title=form.cleaned_data['title'], | |||
notice_text=form.cleaned_data['text'], | |||
pub_start=form.cleaned_data['start'], | |||
pub_end=form.cleaned_data['end']) | |||
newNotice.save() | |||
context = {'form' : NoticeForm()} | |||
return render(request, 'posts/edit.html', context) | |||
def delete(request, deleteId=None): | |||
if deleteId != None: | |||
delNotice = Notice.objects.get(id=deleteId) | |||
if delNotice != None: | |||
delNotice.delete() | |||
return redirect('index') | |||
@csrf_exempt | |||
def notice_list(request): | |||
if request.method == 'GET': | |||
notices = Notice.objects.all() | |||
serializer = NoticeSerializer(notices, many=True) | |||
return JsonResponse(serializer.data, safe=False) | |||
elif request.method == 'POST': | |||
data = JSONParser().parse(request) | |||
serializer = NoticeSerializer(data=data) | |||
if serializer.is_valid(): | |||
serializer.save() | |||
return JsonResponse(serializer.data, status=201) | |||
return JsonResponse(serializer.errors, status=400) | |||
@csrf_exempt | |||
def notice_detail(request, id): | |||
try: | |||
notice = Notice.objects.get(id=id) | |||
except Notice.DoesNotExist: | |||
return HttpResponse(status=404) | |||
if request.method == 'GET': | |||
serializer = NoticeSerializer(notice) | |||
return JsonResponse(serializer.data) | |||
elif request.method == 'PUT': | |||
data = JSONParser().parse(request) | |||
serializer = NoticeSerializer(notice, data=data) | |||
if serializer.is_valid(): | |||
serializer.save() | |||
return JsonResponse(serializer.data) | |||
return JsonResponse(serializer.errors, status=400) | |||
elif request.method == 'DELETE': | |||
notice.delete() | |||
return HttpResponse(status=204) | |||
@@ -2,10 +2,14 @@ | |||
<html lang="en"> | |||
<head> | |||
<meta charset="UTF-8"> | |||
{% load static %} | |||
<script src="{% static 'django_eventstream/eventsource.min.js' %}"></script> | |||
<script src="{% static 'django_eventstream/reconnecting-eventsource.js' %}"></script> | |||
<title>{% block title %} {% endblock %}</title> | |||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous"> | |||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap-theme.min.css" integrity="sha384-6pzBo3FDv/PJ8r2KRkGHifhEocL+1X2rVCTTkUfGk7/0pbek5mMa1upzvWbrUbOZ" crossorigin="anonymous"> | |||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js" integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd" crossorigin="anonymous"></script> | |||
</head> | |||
<body> | |||
{% block navigation %} |
@@ -28,7 +28,13 @@ Index | |||
</p> | |||
</div> | |||
<script> | |||
var es = new ReconnectingEventSource('/events/'); | |||
es.addEventListener('message', function (e) {console.log(e.data);location.reload();}, false); | |||
</script> | |||
</form> | |||
{% endblock %} | |||