mirror of
https://github.com/Hopiu/django-tos.git
synced 2026-03-16 20:10:24 +00:00
Merge pull request #3 from cypreess/master
Bug fixes and merge with saebyn commits
This commit is contained in:
commit
559280f043
13 changed files with 172 additions and 71 deletions
|
|
@ -4,3 +4,4 @@ The following is a list of much appreciated contributors:
|
|||
|
||||
Daniel Greenfeld <pydanny@gmail.com>
|
||||
Frank Wiles <frank@revsys.com>
|
||||
Krzysztof Dorosz <cypreess@gmail.com>
|
||||
|
|
|
|||
83
README.rst
83
README.rst
|
|
@ -22,6 +22,83 @@ Installation
|
|||
|
||||
# terms of service links
|
||||
urlpatterns += patterns('',
|
||||
(r'^login/$', 'tos.views.login', {}, 'login',),
|
||||
(r'^terms-of-service/', include('tos.urls')),
|
||||
)
|
||||
url(r'^login/$', 'tos.views.login', {}, 'auth_login',),
|
||||
url(r'^terms-of-service/', include('tos.urls')),
|
||||
)
|
||||
|
||||
|
||||
===============
|
||||
django-tos-i18n
|
||||
===============
|
||||
|
||||
django-tos internationalization using django-modeltranslation.
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
Assuming you have correctly installed django-tos in your app you only need to add following apps to ``INSTALLED_APPS``::
|
||||
|
||||
INSTALLED_APPS += ('modeltranslation', 'tos_i18n')
|
||||
|
||||
and also you should also define your languages in django ``LANG`` variable, eg.::
|
||||
|
||||
LANGUAGES = (
|
||||
('pl', 'Polski'),
|
||||
('en', 'English'),
|
||||
)
|
||||
|
||||
Please note that adding those to ``INSTALLED_APPS`` **changes** django models. Concretely it adds for every registered ``field`` that should translated, additional fields with name ``field_<lang_code>``, e.g. for given model::
|
||||
|
||||
class MyModel(models.Model):
|
||||
name = models.CharField(max_length=10)
|
||||
|
||||
There will be generated fields: ``name`` , ``name_en``, ``name_pl``.
|
||||
|
||||
You should probably migrate your database, using South is recommended. Migrations should be kept in your local project.
|
||||
|
||||
How to migrate tos with South
|
||||
`````````````````````````````
|
||||
|
||||
Here is some step-by-step example how to turn your legacy django-tos instalation synced using syncdb into translated tos with South migrations.
|
||||
|
||||
1. Inform South that you want to store migrations in custom place::
|
||||
|
||||
# Add to INSTALLED_APS
|
||||
SOUTH_MIGRATION_MODULES = {
|
||||
'tos': 'YOUR_APP.migrations.tos',
|
||||
}
|
||||
|
||||
2. Add required directory (django package)::
|
||||
|
||||
mkdir -p YOUR_APP/migrations/tos
|
||||
touch YOUR_APP/migrations/tos/__init__.py
|
||||
|
||||
3. Create initial migration (referring to the database state as it is now)::
|
||||
|
||||
python manage.py schemamigration --initial tos
|
||||
|
||||
4. Fake migration (because the changes are already in the database)::
|
||||
|
||||
python manage.py migrate tos --fake
|
||||
|
||||
5. Install tos_i18n to INSTALLED_APPS::
|
||||
|
||||
INSTALLED_APS += ('tos_i18n', )
|
||||
|
||||
6. Migrate what changed::
|
||||
|
||||
$ python manage.py schemamigration --auto tos
|
||||
$ python migrate tos
|
||||
|
||||
|
||||
That's it. You are now running tos in i18n mode with languages you declared in LANGUAGES setting.
|
||||
|
||||
This app will also make all required adjustments in django admin.
|
||||
|
||||
For more info on how translation works in details please refer to `django-modeltranslation docs<https://django-modeltranslation.readthedocs.org/en/latest/>`_.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
VERSION = (0, 1, 0)
|
||||
VERSION = (0, 1, 1)
|
||||
|
|
@ -1,68 +1,72 @@
|
|||
from django.core.exceptions import ValidationError
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.db import models
|
||||
from django.contrib.auth.models import User
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
|
||||
class NoActiveTermsOfService(ValidationError):
|
||||
pass
|
||||
|
||||
class NoActiveTermsOfService(ValidationError): pass
|
||||
|
||||
class BaseModel(models.Model):
|
||||
|
||||
created = models.DateTimeField(auto_now_add=True, editable=False)
|
||||
modified = models.DateTimeField(auto_now=True, editable=False)
|
||||
|
||||
created = models.DateTimeField(auto_now_add=True, editable=False)
|
||||
modified = models.DateTimeField(auto_now=True, editable=False)
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
|
||||
|
||||
class TermsOfServiceManager(models.Manager):
|
||||
|
||||
def get_current_tos(self):
|
||||
try:
|
||||
return self.get(active=True)
|
||||
return self.get(active=True)
|
||||
except self.model.DoesNotExist:
|
||||
raise NoActiveTermsOfService('Please create an active Terms-of-Service')
|
||||
raise NoActiveTermsOfService(u'Please create an active Terms-of-Service')
|
||||
|
||||
|
||||
class TermsOfService(BaseModel):
|
||||
active = models.BooleanField(verbose_name=_('active'),
|
||||
help_text=_(u'Only one terms of service is allowed to be active'))
|
||||
content = models.TextField(verbose_name=_('content'), blank=True)
|
||||
objects = TermsOfServiceManager()
|
||||
|
||||
active = models.BooleanField(_('active'), _('Only one terms of service is allowed to be active'))
|
||||
content = models.TextField(_('content'), blank=True)
|
||||
objects = TermsOfServiceManager()
|
||||
|
||||
class Meta:
|
||||
class Meta:
|
||||
get_latest_by = 'created'
|
||||
ordering = ('-created',)
|
||||
verbose_name=_('Terms of Service')
|
||||
verbose_name_plural=_('Terms of Service')
|
||||
verbose_name = _('Terms of Service')
|
||||
verbose_name_plural = _('Terms of Service')
|
||||
|
||||
def __unicode__(self):
|
||||
active = 'inactive'
|
||||
if self.active:
|
||||
active = 'active'
|
||||
active = 'active'
|
||||
return '%s: %s' % (self.created, active)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
""" Ensure we're being saved properly """
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
""" Ensure we're being saved properly """
|
||||
|
||||
if self.active:
|
||||
TermsOfService.objects.exclude(id=self.id).update(active=False)
|
||||
|
||||
else:
|
||||
if not TermsOfService.objects.exclude(id=self.id).filter(active=True):
|
||||
raise NoActiveTermsOfService('One of the terms of service must be marked active')
|
||||
|
||||
super(TermsOfService,self).save(*args, **kwargs)
|
||||
|
||||
else:
|
||||
if not TermsOfService.objects\
|
||||
.exclude(id=self.id)\
|
||||
.filter(active=True):
|
||||
raise NoActiveTermsOfService(u'One of the terms of service must be marked active')
|
||||
|
||||
super(TermsOfService, self).save(*args, **kwargs)
|
||||
|
||||
|
||||
class UserAgreement(BaseModel):
|
||||
|
||||
terms_of_service = models.ForeignKey(TermsOfService, related_name='terms')
|
||||
user = models.ForeignKey(User, related_name='user_agreement')
|
||||
|
||||
user = models.ForeignKey(User, related_name='user_agreement')
|
||||
|
||||
def __unicode__(self):
|
||||
return '%s agreed to TOS: %s ' % (self.user.username, self.terms_of_service.__unicode__())
|
||||
|
||||
|
||||
return u'%s agreed to TOS: %s' % (self.user.username,
|
||||
unicode(self.terms_of_service))
|
||||
|
||||
|
||||
def has_user_agreed_latest_tos(user):
|
||||
if UserAgreement.objects.filter(terms_of_service=TermsOfService.objects.get_current_tos(),user=user):
|
||||
if UserAgreement.objects.filter(terms_of_service=TermsOfService.objects.get_current_tos(), user=user):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
{% load url from future %}
|
||||
{% if note %}
|
||||
<h2>{{ note }}</note>
|
||||
{% else %}
|
||||
|
|
@ -8,7 +9,7 @@
|
|||
|
||||
<h2>Accept Terms of Service?</h2>
|
||||
|
||||
<form method="post" action="{% url tos_check_tos %}">
|
||||
<form method="post" action="{% url "tos_check_tos" %}">
|
||||
{% csrf_token %}
|
||||
<input type="submit" name="accept" value="accept">
|
||||
<input type="submit" name="accept" value="reject">
|
||||
|
|
|
|||
24
tos/urls.py
24
tos/urls.py
|
|
@ -1,26 +1,10 @@
|
|||
from django.conf.urls.defaults import *
|
||||
from django.views.generic.simple import direct_to_template
|
||||
|
||||
from tos.models import TermsOfService
|
||||
from tos.views import check_tos
|
||||
from django.conf.urls import url, patterns
|
||||
from tos.views import check_tos, TosView
|
||||
|
||||
urlpatterns = patterns('',
|
||||
# Terms of Service conform
|
||||
url(
|
||||
regex = '^confirm/$',
|
||||
view = check_tos,
|
||||
name = 'tos_check_tos',
|
||||
),
|
||||
url(r'^confirm/$', check_tos, name='tos_check_tos'),
|
||||
|
||||
# Terms of service simple display
|
||||
url(
|
||||
regex = '^$',
|
||||
view = direct_to_template,
|
||||
kwargs = {'template': 'tos/tos.html',
|
||||
'extra_context':{
|
||||
'tos':TermsOfService.objects.get_current_tos()
|
||||
},
|
||||
},
|
||||
name = 'tos',
|
||||
),
|
||||
url(r'^$', TosView.as_view(), name='tos'),
|
||||
)
|
||||
28
tos/views.py
28
tos/views.py
|
|
@ -1,17 +1,29 @@
|
|||
from django.views.generic import TemplateView
|
||||
import re
|
||||
from django.conf import settings
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth import login as auth_login
|
||||
from django.contrib.auth import REDIRECT_FIELD_NAME
|
||||
from django.contrib.auth.forms import AuthenticationForm
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.sites.models import Site, RequestSite
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.shortcuts import render_to_response
|
||||
from django.template import RequestContext
|
||||
from django.views.decorators.cache import never_cache
|
||||
from django.views.decorators.csrf import csrf_protect
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from tos.models import has_user_agreed_latest_tos, TermsOfService, UserAgreement
|
||||
|
||||
class TosView(TemplateView):
|
||||
template_name = "tos/tos.html"
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(TosView, self).get_context_data(**kwargs)
|
||||
context['tos'] = TermsOfService.objects.get_current_tos()
|
||||
return context
|
||||
|
||||
|
||||
def _redirect_to(redirect_to):
|
||||
""" Moved redirect_to logic here to avoid duplication in views"""
|
||||
|
||||
|
|
@ -31,13 +43,9 @@ def _redirect_to(redirect_to):
|
|||
@never_cache
|
||||
def check_tos(request, template_name='tos/tos_check.html',
|
||||
redirect_field_name=REDIRECT_FIELD_NAME,):
|
||||
|
||||
|
||||
redirect_to = _redirect_to(request.REQUEST.get(redirect_field_name, ''))
|
||||
|
||||
note=""
|
||||
|
||||
tos = TermsOfService.objects.get_current_tos()
|
||||
|
||||
if request.method=="POST":
|
||||
if request.POST.get("accept", "") == "accept":
|
||||
user = request.session['tos_user']
|
||||
|
|
@ -53,12 +61,12 @@ def check_tos(request, template_name='tos/tos_check.html',
|
|||
|
||||
return HttpResponseRedirect(redirect_to)
|
||||
else:
|
||||
note="You cannot login without agreeing to the terms of this site."
|
||||
messages.error(request, _(u"You cannot login without agreeing to the terms of this site."))
|
||||
|
||||
|
||||
|
||||
return render_to_response(template_name, {
|
||||
'tos':tos,
|
||||
'note':note,
|
||||
|
||||
redirect_field_name: redirect_to,
|
||||
}, context_instance=RequestContext(request))
|
||||
|
||||
|
|
@ -115,7 +123,7 @@ def login(request, template_name='registration/login.html',
|
|||
|
||||
return render_to_response(template_name, {
|
||||
'form': form,
|
||||
'redirect_field_name': redirect_to,
|
||||
redirect_field_name: redirect_to,
|
||||
'site': current_site,
|
||||
'site_name': current_site.name,
|
||||
}, context_instance=RequestContext(request))
|
||||
|
|
|
|||
0
tos_i18n/__init__.py
Normal file
0
tos_i18n/__init__.py
Normal file
13
tos_i18n/admin.py
Normal file
13
tos_i18n/admin.py
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
from django.contrib import admin
|
||||
from modeltranslation.admin import TranslationAdmin
|
||||
from tos.admin import TermsOfServiceAdmin
|
||||
|
||||
# Admin translation for django-plans
|
||||
from tos.models import TermsOfService
|
||||
|
||||
|
||||
class TranslatedTermsOfServiceAdmin(TermsOfServiceAdmin, TranslationAdmin):
|
||||
pass
|
||||
|
||||
admin.site.unregister(TermsOfService)
|
||||
admin.site.register(TermsOfService, TranslatedTermsOfServiceAdmin)
|
||||
3
tos_i18n/models.py
Normal file
3
tos_i18n/models.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
from django.db import models
|
||||
|
||||
# Create your models here.
|
||||
0
tos_i18n/tests.py
Normal file
0
tos_i18n/tests.py
Normal file
9
tos_i18n/translation.py
Normal file
9
tos_i18n/translation.py
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
from modeltranslation.translator import translator, TranslationOptions
|
||||
from tos.models import TermsOfService
|
||||
|
||||
# Translations for django-tos
|
||||
|
||||
class TermsOfServiceTranslationOptions(TranslationOptions):
|
||||
fields = ('content', )
|
||||
|
||||
translator.register(TermsOfService, TermsOfServiceTranslationOptions)
|
||||
1
tos_i18n/views.py
Normal file
1
tos_i18n/views.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
# Create your views here.
|
||||
Loading…
Reference in a new issue