Merge commit 'ee7232cd502afbf15f36769da0835b4a1e1358df' into currency

* commit 'ee7232cd502afbf15f36769da0835b4a1e1358df':
  checkout the production branch on the production server
  add a registration
  disable debugging for production
  add a user profile
  extend the base template with login, profile and logout links
  add templates to support user authentication
  add url patterns to support user authentication
  remove an unnecessary shebang
  remove unnecessary attributes from the Person model
  redirect logins back to the index
  make imports more explicit
  remove an unnecessary configuration
  remove an old file
  change the article status to active
  change the content include because the org-mode file is called doku
  add a python package to the ansible role
  add fixtures with test data
  fix the admin view of order of goods
  added sketch of Siteview to docs
This commit is contained in:
Ivan Hörler 2017-12-29 19:28:31 +01:00
commit 487c96710a
20 changed files with 258 additions and 42 deletions

2
Vagrantfile vendored
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 = '/'

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,6 @@
{% extends 'webshop/base.html' %}
{% block section_title %}You have been successfully logged out.{% endblock %}
{% block content %}
{% endblock %}

View File

@ -0,0 +1,12 @@
{% extends 'webshop/base.html' %}
{% block section_title %}Login{% endblock %}
{% block content %}
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Login</button>
<p><a href="{% url 'registration' %}">Go to registration.</a></p>
</form>
{% endblock %}

View File

@ -0,0 +1,17 @@
{% extends 'webshop/base.html' %}
{% block section_title %}User Profile{% endblock %}
{% block content %}
<p><b>Username: </b>{{ request.user.username }}</p>
<p><b>Salutation: </b>{{ person.salutation }}</p>
<p><b>Firstname: </b>{{ request.user.first_name }}</p>
<p><b>Lastname: </b>{{ request.user.last_name }}</p>
<p><b>City: </b>{{ person.city }}</p>
<p><b>Street: </b>{{ person.street_name }}</p>
<p><b>Streetnumber: </b>{{ person.street_number }}</p>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
</form>
{% endblock %}

View File

@ -0,0 +1,19 @@
{% extends 'webshop/base.html' %}
{% block section_title %}Registration{% endblock %}
{% block content %}
{% if profile_form.errors %}
<p style="color: red;">
Please correct the error{{ form.errors|pluralize }} below.
</p>
{% endif %}
<form action="" method="post" novalidate>
<table>
{{ user_form.as_table }}
{{ profile_form.as_table }}
</table>
{% csrf_token %}
<button type="submit">Register</button>
</form>
{% endblock %}

View File

@ -4,6 +4,12 @@
</head>
<body>
<div id="content" class="flex">
<a href="{% url 'index' %}">Home</a> |
{% if user.is_authenticated %}
<a href="{% url 'profile' %}">Profile</a> | <a href="{% url 'logout' %}">Logout</a>
{% else %}
<a href="{% url 'login' %}">Login</a>
{% endif %}
<h1>{% block section_title %}Music Instrument Shop{% endblock %}</h1>
{% block content %}{% endblock %}
</div>

View File

@ -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<category_id>[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'),
]

View File

@ -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})

View File

@ -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

View File

@ -11,7 +11,7 @@
\microtypesetup{protrusion=true} % enables protrusion
\newpage
\include{content}
\include{doku}
\newpage
\nocite{*}

Binary file not shown.

After

Width:  |  Height:  |  Size: 320 KiB

View File

@ -1,20 +0,0 @@
<!DOCTYPE HTML>
<meta charset="UTF-8">
<html>
<head></head>
<body>
<header>
<h1>audioguide</h1>
<h3>a mobile offline audioguide</h3>
noop
noop
noop
noop
noop
noop
<p>the audioguide that makes a offline usage possible.</p>
</header>
<nav>
</nav>
</body>
</html>

View File

@ -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)