diff --git a/Vagrantfile b/Vagrantfile index 7e8c3d7..a8fe782 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -30,7 +30,7 @@ Vagrant.configure("2") do |config| #zu installierende Pakete apt-get install -y apache2 python3-django mariadb-server avahi-daemon \ libnss-mdns libapache2-mod-wsgi-py3 python3-mysqldb python3-pip - pip3 install django-extensions Pillow + pip3 install django-extensions Pillow pyaml /vagrant/ansible/roles/web_AI-5/tasks/setup_script.sh SHELL diff --git a/ansible/roles/web_AI-5/tasks/main.yml b/ansible/roles/web_AI-5/tasks/main.yml index e956179..4cab145 100644 --- a/ansible/roles/web_AI-5/tasks/main.yml +++ b/ansible/roles/web_AI-5/tasks/main.yml @@ -15,6 +15,7 @@ git: repo=https://git.2li.ch/ibz/web_AI-5.git dest="/vagrant" force=yes + version=production - name: Set Permissions on the repository file: @@ -27,6 +28,7 @@ name: - django-extensions - Pillow + - pyaml executable: pip3 - name: Run the setup script to add some final touches diff --git a/ansible/roles/web_AI-5/tasks/setup_script.sh b/ansible/roles/web_AI-5/tasks/setup_script.sh index d9ed1c3..6243fb4 100755 --- a/ansible/roles/web_AI-5/tasks/setup_script.sh +++ b/ansible/roles/web_AI-5/tasks/setup_script.sh @@ -17,3 +17,5 @@ echo "from django.contrib.auth.models import User; \ User.objects.filter(email='admin@example.com').delete(); \ User.objects.create_superuser('admin', 'admin@example.com', 'password')" | python3 /vagrant/django/didgeridoo/manage.py shell + +python3 /vagrant/django/didgeridoo/manage.py loaddata webshop diff --git a/django/didgeridoo/didgeridoo/settings.py b/django/didgeridoo/didgeridoo/settings.py index 33c98f9..61bc7e1 100644 --- a/django/didgeridoo/didgeridoo/settings.py +++ b/django/didgeridoo/didgeridoo/settings.py @@ -23,9 +23,13 @@ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) SECRET_KEY = '(#4#-$$&mx7(%q+6&&@-c&g%i0dc4)zfks1%sy8b%lsxspou&%' # SECURITY WARNING: don't run with debug turned on in production! -DEBUG = True +DEBUG = False -ALLOWED_HOSTS = [] +ALLOWED_HOSTS = [ + 'localhost', + '127.0.0.1', + 'didgeridoo.ml' +] # Application definition @@ -131,9 +135,4 @@ STATIC_URL = '/static/' STATIC_ROOT = '/vagrant/django/didgeridoo/static/' MEDIA_ROOT = '/vagrant/django/didgeridoo/media/' - -ALLOWED_HOSTS = [ - 'localhost', - '127.0.0.1', - 'didgeridoo.ml' -] +LOGIN_REDIRECT_URL = '/' diff --git a/django/didgeridoo/webshop/admin.py b/django/didgeridoo/webshop/admin.py index 3ec97e8..06b4dd4 100644 --- a/django/didgeridoo/webshop/admin.py +++ b/django/didgeridoo/webshop/admin.py @@ -3,8 +3,9 @@ from django.contrib.auth.admin import UserAdmin as BaseUserAdmin from django.contrib.auth.models import User # Register your models here. -from .models import (Article, Order, OrderPosition, Person, City, Picture, - OrderOfGoods, Category, Option, Setting) +from webshop.models import (Article, Order, OrderPosition, + Person, City, Picture, OrderOfGoods, + Category, Option, Setting) class PersonInline(admin.StackedInline): @@ -31,6 +32,13 @@ class OrderAdmin(admin.ModelAdmin): inlines = (OrderPositionInline,) +class OrderOfGoodsAdmin(admin.ModelAdmin): + list_display = ('id', 'article', 'order_status', 'order_date') + list_filter = ('order_date',) + date_hierarchy = 'order_date' + ordering = ('-order_date',) + + admin.site.unregister(User) admin.site.register(User, UserAdmin) @@ -38,7 +46,7 @@ admin.site.register(Article) admin.site.register(Order, OrderAdmin) admin.site.register(City) admin.site.register(Picture) -admin.site.register(OrderOfGoods) +admin.site.register(OrderOfGoods, OrderOfGoodsAdmin) admin.site.register(Category) admin.site.register(Option) admin.site.register(Setting) diff --git a/django/didgeridoo/webshop/fixtures/webshop.yaml b/django/didgeridoo/webshop/fixtures/webshop.yaml new file mode 100644 index 0000000..a3c429d --- /dev/null +++ b/django/didgeridoo/webshop/fixtures/webshop.yaml @@ -0,0 +1,97 @@ +- model: webshop.Category + fields: + name: "First Parent Category" + parent_category: +- model: webshop.Category + fields: + name: "Second Parent Category" + parent_category: +- model: webshop.Category + fields: + name: "Third Parent Category" + parent_category: +- model: webshop.Category + fields: + name: "Fourth Parent Category" + parent_category: +- model: webshop.Category + fields: + name: "Child Category 1" + parent_category: 1 +- model: webshop.Category + fields: + name: "Child Category 2" + parent_category: 2 +- model: webshop.Category + fields: + name: "Child Category 3" + parent_category: 3 +- model: webshop.Category + fields: + name: "Child Category 4" + parent_category: 4 + +- model: webshop.Article + fields: + name: "Article of First Parent Category" + category: 1 + description: "An article sorted under the First Parent Category." + stock: 10 + status: 3 + price_in_chf: 10.1 +- model: webshop.Article + fields: + name: "Article of Second Parent Category" + category: 2 + description: "An article sorted under the Second Parent Category." + stock: 20 + status: 3 + price_in_chf: 20.2 +- model: webshop.Article + fields: + name: "Article of Third Parent Category" + category: 3 + description: "An article sorted under the Third Parent Category." + stock: 30 + status: 3 + price_in_chf: 30.3 +- model: webshop.Article + fields: + name: "Article of Fourth Parent Category" + category: 4 + description: "An article sorted under the Fourth Parent Category." + stock: 40 + status: 3 + price_in_chf: 40.4 +- model: webshop.Article + fields: + name: "Article of Child Category 1" + category: 5 + description: "An article sorted under the Child Category 1." + stock: 11 + status: 3 + price_in_chf: 11.1 +- model: webshop.Article + fields: + name: "Article of Child Category 2" + category: 6 + description: "An article sorted under the Child Category 2." + stock: 22 + status: 3 + price_in_chf: 21.2 +- model: webshop.Article + fields: + name: "Article of Child Category 3" + category: 7 + description: "An article sorted under the Child Category 3." + stock: 33 + status: 3 + price_in_chf: 31.3 +- model: webshop.Article + fields: + name: "Article of Child Category 4" + category: 8 + description: "An article sorted under the Child Category 4." + stock: 44 + status: 3 + price_in_chf: 41.4 diff --git a/django/didgeridoo/webshop/forms.py b/django/didgeridoo/webshop/forms.py new file mode 100644 index 0000000..c87ec6c --- /dev/null +++ b/django/didgeridoo/webshop/forms.py @@ -0,0 +1,24 @@ +from django import forms +from webshop.models import Salutation, City + + +class RegistrationForm(forms.Form): + email = forms.EmailField() + salutation = forms.ModelChoiceField(queryset=Salutation.objects.all()) + first_name = forms.CharField() + last_name = forms.CharField() + street_name = forms.CharField() + street_number = forms.CharField() + zip_code = forms.IntegerField(min_value=1000, max_value=9999) + city = forms.CharField() + + def clean_city(self): + # Check that the two password entries match + city = self.cleaned_data['city'] + zip_code = self.cleaned_data['zip_code'] + try: + City.objects.get(name=city, zip_code=zip_code) + except City.DoesNotExist: + raise forms.ValidationError( + "The zip code and the city don't match.") + return city diff --git a/django/didgeridoo/webshop/models.py b/django/didgeridoo/webshop/models.py index c31c65b..ecb6678 100644 --- a/django/didgeridoo/webshop/models.py +++ b/django/didgeridoo/webshop/models.py @@ -1,5 +1,3 @@ -#!/usr/bin/python3 - from decimal import Decimal from django.core.validators import MinValueValidator from django.db import models @@ -130,8 +128,6 @@ class Salutation(models.Model): class Person(models.Model): - first_name = models.CharField(max_length=200) - last_name = models.CharField(max_length=200) salutation = models.ForeignKey(Salutation) city = models.ForeignKey(City) street_name = models.CharField(max_length=200) @@ -139,4 +135,4 @@ class Person(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) def __str__(self): - return self.last_name + return self.user.username diff --git a/django/didgeridoo/webshop/templates/registration/logged_out.html b/django/didgeridoo/webshop/templates/registration/logged_out.html new file mode 100644 index 0000000..866f568 --- /dev/null +++ b/django/didgeridoo/webshop/templates/registration/logged_out.html @@ -0,0 +1,6 @@ +{% extends 'webshop/base.html' %} + +{% block section_title %}You have been successfully logged out.{% endblock %} + +{% block content %} +{% endblock %} diff --git a/django/didgeridoo/webshop/templates/registration/login.html b/django/didgeridoo/webshop/templates/registration/login.html new file mode 100644 index 0000000..4ff603e --- /dev/null +++ b/django/didgeridoo/webshop/templates/registration/login.html @@ -0,0 +1,12 @@ +{% extends 'webshop/base.html' %} + +{% block section_title %}Login{% endblock %} + +{% block content %} +
+ {% csrf_token %} + {{ form.as_p }} + +

Go to registration.

+
+{% endblock %} diff --git a/django/didgeridoo/webshop/templates/registration/profile.html b/django/didgeridoo/webshop/templates/registration/profile.html new file mode 100644 index 0000000..ed2e406 --- /dev/null +++ b/django/didgeridoo/webshop/templates/registration/profile.html @@ -0,0 +1,17 @@ +{% extends 'webshop/base.html' %} + +{% block section_title %}User Profile{% endblock %} + +{% block content %} +

Username: {{ request.user.username }}

+

Salutation: {{ person.salutation }}

+

Firstname: {{ request.user.first_name }}

+

Lastname: {{ request.user.last_name }}

+

City: {{ person.city }}

+

Street: {{ person.street_name }}

+

Streetnumber: {{ person.street_number }}

+
+ {% csrf_token %} + {{ form.as_p }} +
+{% endblock %} diff --git a/django/didgeridoo/webshop/templates/registration/register.html b/django/didgeridoo/webshop/templates/registration/register.html new file mode 100644 index 0000000..032758f --- /dev/null +++ b/django/didgeridoo/webshop/templates/registration/register.html @@ -0,0 +1,19 @@ +{% extends 'webshop/base.html' %} + +{% block section_title %}Registration{% endblock %} + +{% block content %} + {% if profile_form.errors %} +

+ Please correct the error{{ form.errors|pluralize }} below. +

+ {% endif %} +
+ + {{ user_form.as_table }} + {{ profile_form.as_table }} +
+ {% csrf_token %} + +
+{% endblock %} diff --git a/django/didgeridoo/webshop/templates/webshop/base.html b/django/didgeridoo/webshop/templates/webshop/base.html index fa6b702..cf6c6e2 100644 --- a/django/didgeridoo/webshop/templates/webshop/base.html +++ b/django/didgeridoo/webshop/templates/webshop/base.html @@ -4,6 +4,12 @@
+ Home | + {% if user.is_authenticated %} + Profile | Logout + {% else %} + Login + {% endif %}

{% block section_title %}Music Instrument Shop{% endblock %}

{% block content %}{% endblock %}
diff --git a/django/didgeridoo/webshop/urls.py b/django/didgeridoo/webshop/urls.py index ae62468..dc79c1d 100644 --- a/django/didgeridoo/webshop/urls.py +++ b/django/didgeridoo/webshop/urls.py @@ -1,6 +1,6 @@ -from django.conf.urls import url +from django.conf.urls import url, include -from . import views +from webshop import views urlpatterns = [ url(r'^$', views.index, name='index'), @@ -10,4 +10,7 @@ urlpatterns = [ url(r'^category/(?P[0-9]+)/$', views.articles_in_category, name='category'), + url('^', include('django.contrib.auth.urls')), + url(r'^profile/$', views.profile, name='profile'), + url(r'^registration/$', views.registration, name='registration'), ] diff --git a/django/didgeridoo/webshop/views.py b/django/didgeridoo/webshop/views.py index 046ae5f..499c261 100644 --- a/django/didgeridoo/webshop/views.py +++ b/django/didgeridoo/webshop/views.py @@ -1,5 +1,10 @@ +from django.http import HttpResponseRedirect from django.shortcuts import get_object_or_404, render -from .models import Article, Category, ArticleStatus +from django.contrib.auth.decorators import login_required +from django.contrib.auth.models import User +from django.contrib.auth.forms import UserCreationForm +from webshop.models import Article, Category, ArticleStatus, Person, City +from webshop.forms import RegistrationForm # Create your views here. @@ -33,3 +38,39 @@ def article_details(request, article_id): article = get_object_or_404(Article, pk=article_id) return render(request, 'webshop/article_details.html', {'article': article}) + + +@login_required +def profile(request): + person = Person.objects.get(user=request.user) + return render(request, 'registration/profile.html', + {'person': person}) + + +def registration(request): + if request.method == 'POST': + profile_form = RegistrationForm(request.POST) + user_form = UserCreationForm(request.POST) + if (profile_form.is_valid() and user_form.is_valid()): + pf = profile_form.cleaned_data + uf = user_form.cleaned_data + user = User.objects.create_user(uf['username'], + pf['email'], + uf['password2']) + user.last_name = pf['last_name'] + user.first_name = pf['first_name'] + user.save() + person = Person.objects.create( + salutation=pf['salutation'], + city=City.objects.get(zip_code=pf['zip_code'], + name=pf['city']), + street_name=pf['street_name'], + street_number=pf['street_number'], + user=user) + return HttpResponseRedirect('/login/') + else: + profile_form = RegistrationForm + user_form = UserCreationForm + return render(request, 'registration/register.html', + {'profile_form': profile_form, + 'user_form': user_form}) diff --git a/docs/doku.org b/docs/doku.org index dc3f811..41127b9 100644 --- a/docs/doku.org +++ b/docs/doku.org @@ -201,6 +201,10 @@ Am ende des Projekts die nicht lauffähigen teile ausgrenzen. :-) * Umsetzung ** Spezifikation +*** Mockup +#+ATTR_LATEX: :width 18cm +#+CAPTION: a early Mockup of the shop +[[file:pictures/mockup-full-snipet.png][file:pictures/mockup-full-snipet.png] *** Anwendungsfälle *** Klassendiagramme der Models diff --git a/docs/main.tex b/docs/main.tex index 3c774f0..fa3976b 100644 --- a/docs/main.tex +++ b/docs/main.tex @@ -11,7 +11,7 @@ \microtypesetup{protrusion=true} % enables protrusion \newpage -\include{content} +\include{doku} \newpage \nocite{*} diff --git a/docs/pictures/mockup-full-snipet.png b/docs/pictures/mockup-full-snipet.png new file mode 100644 index 0000000..f78ed3b Binary files /dev/null and b/docs/pictures/mockup-full-snipet.png differ diff --git a/html/index.html b/html/index.html deleted file mode 100644 index 6bc0653..0000000 --- a/html/index.html +++ /dev/null @@ -1,20 +0,0 @@ - - - - - -
-

audioguide

-

a mobile offline audioguide

- noop - noop - noop - noop - noop - noop -

the audioguide that makes a offline usage possible.

-
- - - diff --git a/sql/02_insert_data.sql b/sql/02_insert_data.sql index 6689176..8c31e0b 100644 --- a/sql/02_insert_data.sql +++ b/sql/02_insert_data.sql @@ -24,7 +24,7 @@ use webshopdb; insert into webshop_articlestatus (name) values ('out of stock'), ('hidden'), - ('on sale'); + ('active'); use webshopdb; insert into webshop_city (zip_code, name)