implement adding websites

- implement websites.models.Website
- add migration
- implement websites.views.AddWebsite
- implement websites.forms.AddWebsiteForm
- define URL pattern 'add_website' in websites.urls
- register Website model in websites.admin
- add templates websites/base.html and websites/website_create.html
- add german translation for new strings
- add website URLs to gnuviechadmin.urls
- add websites to INSTALLED_APPS
- add changelog entry
This commit is contained in:
Jan Dittberner 2015-01-26 22:47:49 +01:00
parent cff35dd408
commit 711a96212c
12 changed files with 297 additions and 5 deletions

View File

@ -1,6 +1,7 @@
Changelog
=========
* :feature:`-` implement setup of websites
* :support:`-` add webtasks interface
* :support:`-` update to new fileservertasks interface (requires gvafile >=
0.4.0 on the fileserver)

View File

@ -265,6 +265,7 @@ LOCAL_APPS = (
'managemails',
'userdbs',
'hostingpackages',
'websites',
)
# See: https://docs.djangoproject.com/en/dev/ref/settings/#installed-apps

View File

@ -13,6 +13,7 @@ urlpatterns = patterns(
url(r'^database/', include('userdbs.urls')),
url(r'^domains/', include('domains.urls')),
url(r'^hosting/', include('hostingpackages.urls')),
url(r'^website/', include('websites.urls')),
url(r'^mail/', include('managemails.urls')),
url(r'^osuser/', include('osusers.urls')),
url(r'^admin/', include(admin.site.urls)),

View File

@ -0,0 +1 @@
{% extends "base.html" %}

View File

@ -0,0 +1,30 @@
{% extends "websites/base.html" %}
{% load i18n crispy_forms_tags %}
{% block title %}{{ block.super }} - {% spaceless %}
{% if user == customer %}
{% blocktrans with domain=domain.domain %}Add Website for Subdomain of {{ domain }}{% endblocktrans %}
{% else %}
{% blocktrans with domain=domain.domain full_name=customer.get_full_name %}Add Website for Subdomain of Domain {{ domain }} of Customer {{ full_name }}{% endblocktrans %}
{% endif %}
{% endspaceless %}{% endblock title %}
{% block page_title %}{% spaceless %}
{% if user == customer %}
{% blocktrans with domain=domain.domain %}Add Website <small>for Subdomain of {{ domain }}</small>{% endblocktrans %}
{% else %}
{% blocktrans with domain=domain.domain full_name=customer.get_full_name %}Add Website <small>for Subdomain of Domain {{ domain }} of Customer {{ full_name }}</small>{% endblocktrans %}
{% endif %}
{% endspaceless %}{% endblock page_title %}
{% block content %}
{% crispy form %}
{% endblock %}
{% block extra_js %}
<script type="text/javascript">
$(document).ready(function() {
$('input[type=text]').first().focus();
});
</script>
{% endblock extra_js %}

View File

@ -1,3 +1,12 @@
"""
Admin site for websites.
"""
from __future__ import absolute_import
from django.contrib import admin
# Register your models here.
from .models import Website
admin.site.register(Website)

View File

@ -0,0 +1,62 @@
"""
This module defines form classes for website editing.
"""
from __future__ import absolute_import, unicode_literals
from django import forms
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext as _
from crispy_forms.bootstrap import AppendedText
from crispy_forms.helper import FormHelper
from crispy_forms.layout import (
Layout,
Submit,
)
from .models import Website
class AddWebsiteForm(forms.ModelForm):
"""
This form is used to create new Website instances.
"""
class Meta:
model = Website
fields = ['subdomain', 'wildcard']
def __init__(self, *args, **kwargs):
self.hosting_package = kwargs.pop('hostingpackage')
self.hosting_domain = kwargs.pop('domain')
super(AddWebsiteForm, self).__init__(*args, **kwargs)
if Website.objects.filter(wildcard=True).exists():
self.fields['wildcard'].widget = forms.HiddenInput()
self.helper = FormHelper()
self.helper.form_action = reverse(
'add_website', kwargs={
'package': self.hosting_package.id,
'domain': self.hosting_domain.domain,
}
)
self.helper.layout = Layout(
AppendedText('subdomain', '.' + self.hosting_domain.domain),
'wildcard',
Submit('submit', _('Add website')),
)
def clean_subdomain(self):
data = self.cleaned_data['subdomain']
if Website.objects.filter(
domain=self.hosting_domain, subdomain=data
).exists():
raise forms.ValidationError(
_('There is already a website for this subdomain'))
return data
def save(self, commit=True):
self.instance.domain = self.hosting_domain
self.instance.osuser = self.hosting_package.osuser
return super(AddWebsiteForm, self).save(commit)

View File

@ -0,0 +1,44 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: websites gnuviechadmin app\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-01-26 21:37+0100\n"
"PO-Revision-Date: 2015-01-26 21:39+0100\n"
"Last-Translator: Jan Dittberner <jan@dittberner.info>\n"
"Language-Team: Jan Dittberner <jan@dittberner.info>\n"
"Language: de\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 1.6.10\n"
"X-Poedit-SourceCharset: UTF-8\n"
#: models.py:22
msgid "sub domain"
msgstr "Subdomain"
#: models.py:24
msgid "operating system user"
msgstr "Betriebssystemnutzer"
#: models.py:26
msgid "domain"
msgstr "Domain"
#: models.py:27
msgid "wildcard"
msgstr "Wildcard"
#: models.py:31
msgid "website"
msgstr "Webauftritt"
#: models.py:32
msgid "websites"
msgstr "Webauftritte"

View File

@ -0,0 +1,34 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('osusers', '0004_auto_20150104_1751'),
('domains', '0002_auto_20150124_1909'),
]
operations = [
migrations.CreateModel(
name='Website',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('subdomain', models.CharField(max_length=64, verbose_name='sub domain')),
('wildcard', models.BooleanField(default=False, verbose_name='wildcard')),
('domain', models.ForeignKey(verbose_name='domain', to='domains.HostingDomain')),
('osuser', models.ForeignKey(verbose_name='operating system user', to='osusers.User')),
],
options={
'verbose_name': 'website',
'verbose_name_plural': 'websites',
},
bases=(models.Model,),
),
migrations.AlterUniqueTogether(
name='website',
unique_together=set([('domain', 'subdomain')]),
),
]

View File

@ -1,3 +1,37 @@
from django.db import models
"""
This module defines the database models for website handling.
# Create your models here.
"""
from __future__ import absolute_import, unicode_literals
from django.db import models
from django.utils.encoding import python_2_unicode_compatible
from django.utils.translation import ugettext as _
from domains.models import HostingDomain
from osusers.models import User as OsUser
@python_2_unicode_compatible
class Website(models.Model):
"""
This is the model for a website.
"""
subdomain = models.CharField(
_('sub domain'), max_length=64)
osuser = models.ForeignKey(
OsUser, verbose_name=_('operating system user'))
domain = models.ForeignKey(
HostingDomain, verbose_name=_('domain'))
wildcard = models.BooleanField(_('wildcard'), default=False)
class Meta:
unique_together = [('domain', 'subdomain')]
verbose_name = _('website')
verbose_name_plural = _('websites')
def __str__(self):
return "{subdomain}.{domain}".format(
subdomain=self.subdomain, domain=self.domain.domain
)

View File

@ -0,0 +1,18 @@
"""
This module defines the URL patterns for website related views.
"""
from __future__ import absolute_import, unicode_literals
from django.conf.urls import patterns, url
from .views import (
AddWebsite,
)
urlpatterns = patterns(
'',
url(r'^(?P<package>\d+)/(?P<domain>[\w0-9.-]+)/create$',
AddWebsite.as_view(), name='add_website'),
)

View File

@ -1,3 +1,60 @@
from django.shortcuts import render
"""
This module defines views for website handling.
# Create your views here.
"""
from __future__ import absolute_import, unicode_literals
from django.shortcuts import get_object_or_404, redirect
from django.utils.translation import ugettext as _
from django.views.generic.edit import (
CreateView,
)
from django.contrib import messages
from gvacommon.viewmixins import StaffOrSelfLoginRequiredMixin
from gvawebcore.views import HostingPackageAndCustomerMixin
from domains.models import HostingDomain
from .forms import AddWebsiteForm
from .models import Website
class AddWebsite(
HostingPackageAndCustomerMixin, StaffOrSelfLoginRequiredMixin, CreateView
):
"""
This view is used to setup new websites for a customer hosting package.
"""
model = Website
context_object_name = 'website'
template_name_suffix = '_create'
form_class = AddWebsiteForm
def get_form_kwargs(self):
kwargs = super(AddWebsite, self).get_form_kwargs()
kwargs.update({
'hostingpackage': self.get_hosting_package(),
'domain': get_object_or_404(
HostingDomain, domain=self.kwargs['domain']),
})
return kwargs
def get_context_data(self, **kwargs):
context = super(AddWebsite, self).get_context_data(**kwargs)
context.update({
'customer': self.get_customer_object(),
'domain': get_object_or_404(
HostingDomain, domain=self.kwargs['domain'])
})
return context
def form_valid(self, form):
website = form.save()
messages.success(
self.request,
_('Successfully added website {subdomain}.{domain}').format(
subdomain=website.subdomain, domain=website.domain.domain
)
)
return redirect(self.get_hosting_package())