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) | |||||
}) |
""" | |||||
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/' |
"""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') | |||||
] |
""" | |||||
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() |
from django.contrib import admin | |||||
# Register your models here. |
from django.apps import AppConfig | |||||
class PostsConfig(AppConfig): | |||||
name = 'posts' |
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() |
from django.test import TestCase | |||||
# Create your tests here. |
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) | |||||
<html lang="en"> | <html lang="en"> | ||||
<head> | <head> | ||||
<meta charset="UTF-8"> | <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> | <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.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"> | <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> | <script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js" integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd" crossorigin="anonymous"></script> | ||||
</head> | </head> | ||||
<body> | <body> | ||||
{% block navigation %} | {% block navigation %} |
</p> | </p> | ||||
</div> | </div> | ||||
<script> | |||||
var es = new ReconnectingEventSource('/events/'); | |||||
es.addEventListener('message', function (e) {console.log(e.data);location.reload();}, false); | |||||
</script> | |||||
</form> | </form> | ||||
{% endblock %} | {% endblock %} | ||||