Merge branch 'new_django' into 'master'

upgrade to django 2.2

See merge request ae/Sith!243
This commit is contained in:
Antoine Bartuccio 2019-10-12 23:19:26 +02:00
commit 660a3161f5
111 changed files with 1279 additions and 710 deletions

View File

@ -4,6 +4,7 @@ from __future__ import unicode_literals
from django.db import migrations, models from django.db import migrations, models
import django.core.validators import django.core.validators
import accounting.models import accounting.models
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -243,6 +244,7 @@ class Migration(migrations.Migration):
verbose_name="accounting type", verbose_name="accounting type",
to="accounting.AccountingType", to="accounting.AccountingType",
blank=True, blank=True,
on_delete=django.db.models.deletion.CASCADE,
), ),
), ),
], ],
@ -267,6 +269,7 @@ class Migration(migrations.Migration):
verbose_name="simplified accounting types", verbose_name="simplified accounting types",
to="accounting.AccountingType", to="accounting.AccountingType",
related_name="simplified_types", related_name="simplified_types",
on_delete=django.db.models.deletion.CASCADE,
), ),
), ),
], ],

View File

@ -2,6 +2,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import migrations, models from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -22,6 +23,7 @@ class Migration(migrations.Migration):
verbose_name="invoice", verbose_name="invoice",
to="core.SithFile", to="core.SithFile",
blank=True, blank=True,
on_delete=django.db.models.deletion.CASCADE,
), ),
), ),
migrations.AddField( migrations.AddField(
@ -31,12 +33,14 @@ class Migration(migrations.Migration):
verbose_name="journal", verbose_name="journal",
to="accounting.GeneralJournal", to="accounting.GeneralJournal",
related_name="operations", related_name="operations",
on_delete=django.db.models.deletion.CASCADE,
), ),
), ),
migrations.AddField( migrations.AddField(
model_name="operation", model_name="operation",
name="linked_operation", name="linked_operation",
field=models.OneToOneField( field=models.OneToOneField(
on_delete=django.db.models.deletion.CASCADE,
blank=True, blank=True,
to="accounting.Operation", to="accounting.Operation",
null=True, null=True,
@ -54,6 +58,7 @@ class Migration(migrations.Migration):
verbose_name="simple type", verbose_name="simple type",
to="accounting.SimplifiedAccountingType", to="accounting.SimplifiedAccountingType",
blank=True, blank=True,
on_delete=django.db.models.deletion.CASCADE,
), ),
), ),
migrations.AddField( migrations.AddField(
@ -63,6 +68,7 @@ class Migration(migrations.Migration):
verbose_name="club account", verbose_name="club account",
to="accounting.ClubAccount", to="accounting.ClubAccount",
related_name="journals", related_name="journals",
on_delete=django.db.models.deletion.CASCADE,
), ),
), ),
migrations.AddField( migrations.AddField(
@ -72,20 +78,27 @@ class Migration(migrations.Migration):
verbose_name="bank account", verbose_name="bank account",
to="accounting.BankAccount", to="accounting.BankAccount",
related_name="club_accounts", related_name="club_accounts",
on_delete=django.db.models.deletion.CASCADE,
), ),
), ),
migrations.AddField( migrations.AddField(
model_name="clubaccount", model_name="clubaccount",
name="club", name="club",
field=models.ForeignKey( field=models.ForeignKey(
verbose_name="club", to="club.Club", related_name="club_account" verbose_name="club",
to="club.Club",
related_name="club_account",
on_delete=django.db.models.deletion.CASCADE,
), ),
), ),
migrations.AddField( migrations.AddField(
model_name="bankaccount", model_name="bankaccount",
name="club", name="club",
field=models.ForeignKey( field=models.ForeignKey(
verbose_name="club", to="club.Club", related_name="bank_accounts" verbose_name="club",
to="club.Club",
related_name="bank_accounts",
on_delete=django.db.models.deletion.CASCADE,
), ),
), ),
migrations.AlterUniqueTogether( migrations.AlterUniqueTogether(

View File

@ -29,6 +29,7 @@ class Migration(migrations.Migration):
related_name="labels", related_name="labels",
verbose_name="club account", verbose_name="club account",
to="accounting.ClubAccount", to="accounting.ClubAccount",
on_delete=django.db.models.deletion.CASCADE,
), ),
), ),
], ],

View File

@ -22,7 +22,7 @@
# #
# #
from django.core.urlresolvers import reverse from django.urls import reverse
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.core import validators from django.core import validators
from django.db import models from django.db import models
@ -110,7 +110,12 @@ class BankAccount(models.Model):
name = models.CharField(_("name"), max_length=30) name = models.CharField(_("name"), max_length=30)
iban = models.CharField(_("iban"), max_length=255, blank=True) iban = models.CharField(_("iban"), max_length=255, blank=True)
number = models.CharField(_("account number"), max_length=255, blank=True) number = models.CharField(_("account number"), max_length=255, blank=True)
club = models.ForeignKey(Club, related_name="bank_accounts", verbose_name=_("club")) club = models.ForeignKey(
Club,
related_name="bank_accounts",
verbose_name=_("club"),
on_delete=models.CASCADE,
)
class Meta: class Meta:
verbose_name = _("Bank account") verbose_name = _("Bank account")
@ -136,9 +141,17 @@ class BankAccount(models.Model):
class ClubAccount(models.Model): class ClubAccount(models.Model):
name = models.CharField(_("name"), max_length=30) name = models.CharField(_("name"), max_length=30)
club = models.ForeignKey(Club, related_name="club_account", verbose_name=_("club")) club = models.ForeignKey(
Club,
related_name="club_account",
verbose_name=_("club"),
on_delete=models.CASCADE,
)
bank_account = models.ForeignKey( bank_account = models.ForeignKey(
BankAccount, related_name="club_accounts", verbose_name=_("bank account") BankAccount,
related_name="club_accounts",
verbose_name=_("bank account"),
on_delete=models.CASCADE,
) )
class Meta: class Meta:
@ -203,7 +216,11 @@ class GeneralJournal(models.Model):
name = models.CharField(_("name"), max_length=40) name = models.CharField(_("name"), max_length=40)
closed = models.BooleanField(_("is closed"), default=False) closed = models.BooleanField(_("is closed"), default=False)
club_account = models.ForeignKey( club_account = models.ForeignKey(
ClubAccount, related_name="journals", null=False, verbose_name=_("club account") ClubAccount,
related_name="journals",
null=False,
verbose_name=_("club account"),
on_delete=models.CASCADE,
) )
amount = CurrencyField(_("amount"), default=0) amount = CurrencyField(_("amount"), default=0)
effective_amount = CurrencyField(_("effective_amount"), default=0) effective_amount = CurrencyField(_("effective_amount"), default=0)
@ -263,7 +280,11 @@ class Operation(models.Model):
number = models.IntegerField(_("number")) number = models.IntegerField(_("number"))
journal = models.ForeignKey( journal = models.ForeignKey(
GeneralJournal, related_name="operations", null=False, verbose_name=_("journal") GeneralJournal,
related_name="operations",
null=False,
verbose_name=_("journal"),
on_delete=models.CASCADE,
) )
amount = CurrencyField(_("amount")) amount = CurrencyField(_("amount"))
date = models.DateField(_("date")) date = models.DateField(_("date"))
@ -282,6 +303,7 @@ class Operation(models.Model):
verbose_name=_("invoice"), verbose_name=_("invoice"),
null=True, null=True,
blank=True, blank=True,
on_delete=models.CASCADE,
) )
done = models.BooleanField(_("is done"), default=False) done = models.BooleanField(_("is done"), default=False)
simpleaccounting_type = models.ForeignKey( simpleaccounting_type = models.ForeignKey(
@ -290,6 +312,7 @@ class Operation(models.Model):
verbose_name=_("simple type"), verbose_name=_("simple type"),
null=True, null=True,
blank=True, blank=True,
on_delete=models.CASCADE,
) )
accounting_type = models.ForeignKey( accounting_type = models.ForeignKey(
"AccountingType", "AccountingType",
@ -297,6 +320,7 @@ class Operation(models.Model):
verbose_name=_("accounting type"), verbose_name=_("accounting type"),
null=True, null=True,
blank=True, blank=True,
on_delete=models.CASCADE,
) )
label = models.ForeignKey( label = models.ForeignKey(
"Label", "Label",
@ -328,6 +352,7 @@ class Operation(models.Model):
null=True, null=True,
blank=True, blank=True,
default=None, default=None,
on_delete=models.CASCADE,
) )
class Meta: class Meta:
@ -487,6 +512,7 @@ class SimplifiedAccountingType(models.Model):
AccountingType, AccountingType,
related_name="simplified_types", related_name="simplified_types",
verbose_name=_("simplified accounting types"), verbose_name=_("simplified accounting types"),
on_delete=models.CASCADE,
) )
class Meta: class Meta:
@ -518,7 +544,10 @@ class Label(models.Model):
name = models.CharField(_("label"), max_length=64) name = models.CharField(_("label"), max_length=64)
club_account = models.ForeignKey( club_account = models.ForeignKey(
ClubAccount, related_name="labels", verbose_name=_("club account") ClubAccount,
related_name="labels",
verbose_name=_("club account"),
on_delete=models.CASCADE,
) )
class Meta: class Meta:

View File

@ -20,14 +20,14 @@
{% for k,v in statement.items() %} {% for k,v in statement.items() %}
<tr> <tr>
<td>{{ k }}</td> <td>{{ k }}</td>
<td>{{ v }}</td> <td>{{ "%.2f" % v }}</td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
<p><strong>{% trans %}Amount: {% endtrans %}</strong>{{ object.amount }} €</p> <p><strong>{% trans %}Amount: {% endtrans %}</strong>{{ "%.2f" % object.amount }} €</p>
<p><strong>{% trans %}Effective amount: {% endtrans %}</strong>{{ object.effective_amount }} €</p> <p><strong>{% trans %}Effective amount: {% endtrans %}</strong>{{ "%.2f" %object.effective_amount }} €</p>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -18,12 +18,12 @@
{% for k,v in dict['CREDIT'].items() %} {% for k,v in dict['CREDIT'].items() %}
<tr> <tr>
<td>{{ k }}</td> <td>{{ k }}</td>
<td>{{ v }}</td> <td>{{ "%.2f" % v }}</td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
{% trans %}Total: {% endtrans %}{{ dict['CREDIT_sum'] }} {% trans %}Total: {% endtrans %}{{ "%.2f" % dict['CREDIT_sum'] }}
<h6>{% trans %}Debit{% endtrans %}</h6> <h6>{% trans %}Debit{% endtrans %}</h6>
<table> <table>
@ -37,19 +37,19 @@
{% for k,v in dict['DEBIT'].items() %} {% for k,v in dict['DEBIT'].items() %}
<tr> <tr>
<td>{{ k }}</td> <td>{{ k }}</td>
<td>{{ v }}</td> <td>{{ "%.2f" % v }}</td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
{% trans %}Total: {% endtrans %}{{ dict['DEBIT_sum'] }} {% trans %}Total: {% endtrans %}{{ "%.2f" % dict['DEBIT_sum'] }}
{% endmacro %} {% endmacro %}
{% block content %} {% block content %}
<h3>{% trans %}Statement by nature: {% endtrans %} {{ object.name }}</h3> <h3>{% trans %}Statement by nature: {% endtrans %} {{ object.name }}</h3>
{% for k,v in statement.items() %} {% for k,v in statement.items() %}
<h4 style="background: lightblue; padding: 4px;">{{ k }} : {{ v['CREDIT_sum'] - v['DEBIT_sum'] }}</h4> <h4 style="background: lightblue; padding: 4px;">{{ k }} : {{ "%.2f" % (v['CREDIT_sum'] - v['DEBIT_sum']) }}</h4>
{{ display_tables(v) }} {{ display_tables(v) }}
<hr> <hr>
{% endfor %} {% endfor %}

View File

@ -28,14 +28,14 @@
{% else %} {% else %}
<td></td> <td></td>
{% endif %} {% endif %}
<td>{{ credit_statement[key] }}</td> <td>{{ "%.2f" % credit_statement[key] }}</td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
<p>Total : {{ total_credit }}</p> <p>Total : {{ "%.2f" % total_credit }}</p>
<h4>{% trans %}Debit{% endtrans %}</h4> <h4>{% trans %}Debit{% endtrans %}</h4>
@ -56,13 +56,13 @@
{% else %} {% else %}
<td></td> <td></td>
{% endif %} {% endif %}
<td>{{ debit_statement[key] }}</td> <td>{{ "%.2f" % debit_statement[key] }}</td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
<p>Total : {{ total_debit }}</p> <p>Total : {{ "%.2f" % total_debit }}</p>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -23,7 +23,7 @@
# #
from django.test import TestCase from django.test import TestCase
from django.core.urlresolvers import reverse from django.urls import reverse
from django.core.management import call_command from django.core.management import call_command
from datetime import date from datetime import date
@ -272,30 +272,50 @@ class OperationTest(TestCase):
def test_nature_statement(self): def test_nature_statement(self):
self.client.login(username="comptable", password="plop") self.client.login(username="comptable", password="plop")
response_get = self.client.get( response = self.client.get(
reverse("accounting:journal_nature_statement", args=[self.journal.id]) reverse("accounting:journal_nature_statement", args=[self.journal.id])
) )
self.assertTrue( self.assertContains(response, "bob (Troll Penché) : 3.00", status_code=200)
"bob (Troll Pench\\xc3\\xa9) : 3.00" in str(response_get.content)
)
def test_person_statement(self): def test_person_statement(self):
self.client.login(username="comptable", password="plop") self.client.login(username="comptable", password="plop")
response_get = self.client.get( response = self.client.get(
reverse("accounting:journal_person_statement", args=[self.journal.id]) reverse("accounting:journal_person_statement", args=[self.journal.id])
) )
self.assertTrue( self.assertContains(response, "Total : 5575.72", status_code=200)
"<td>3.00</td>" in str(response_get.content) self.assertContains(response, "Total : 71.42")
and '<td><a href="/user/1/">S&#39; Kia</a></td>' self.assertContains(
in str(response_get.content) response,
"""
<td><a href="/user/1/">S&#39; Kia</a></td>
<td>3.00</td>""",
)
self.assertContains(
response,
"""
<td><a href="/user/1/">S&#39; Kia</a></td>
<td>823.00</td>""",
) )
def test_accounting_statement(self): def test_accounting_statement(self):
self.client.login(username="comptable", password="plop") self.client.login(username="comptable", password="plop")
response_get = self.client.get( response = self.client.get(
reverse("accounting:journal_accounting_statement", args=[self.journal.id]) reverse("accounting:journal_accounting_statement", args=[self.journal.id])
) )
self.assertTrue( self.assertContains(
"<td>443 - Cr\\xc3\\xa9dit - Ce code n&#39;existe pas</td>" response,
in str(response_get.content) """
<tr>
<td>443 - Crédit - Ce code n&#39;existe pas</td>
<td>3.00</td>
</tr>""",
status_code=200,
)
self.assertContains(
response,
"""
<p><strong>Montant : </strong>-5504.30 </p>
<p><strong>Montant effectif: </strong>-5504.30 </p>""",
) )

View File

@ -22,131 +22,133 @@
# #
# #
from django.conf.urls import url from django.urls import re_path
from accounting.views import * from accounting.views import *
urlpatterns = [ urlpatterns = [
# Accounting types # Accounting types
url( re_path(
r"^simple_type$", r"^simple_type$",
SimplifiedAccountingTypeListView.as_view(), SimplifiedAccountingTypeListView.as_view(),
name="simple_type_list", name="simple_type_list",
), ),
url( re_path(
r"^simple_type/create$", r"^simple_type/create$",
SimplifiedAccountingTypeCreateView.as_view(), SimplifiedAccountingTypeCreateView.as_view(),
name="simple_type_new", name="simple_type_new",
), ),
url( re_path(
r"^simple_type/(?P<type_id>[0-9]+)/edit$", r"^simple_type/(?P<type_id>[0-9]+)/edit$",
SimplifiedAccountingTypeEditView.as_view(), SimplifiedAccountingTypeEditView.as_view(),
name="simple_type_edit", name="simple_type_edit",
), ),
# Accounting types # Accounting types
url(r"^type$", AccountingTypeListView.as_view(), name="type_list"), re_path(r"^type$", AccountingTypeListView.as_view(), name="type_list"),
url(r"^type/create$", AccountingTypeCreateView.as_view(), name="type_new"), re_path(r"^type/create$", AccountingTypeCreateView.as_view(), name="type_new"),
url( re_path(
r"^type/(?P<type_id>[0-9]+)/edit$", r"^type/(?P<type_id>[0-9]+)/edit$",
AccountingTypeEditView.as_view(), AccountingTypeEditView.as_view(),
name="type_edit", name="type_edit",
), ),
# Bank accounts # Bank accounts
url(r"^$", BankAccountListView.as_view(), name="bank_list"), re_path(r"^$", BankAccountListView.as_view(), name="bank_list"),
url(r"^bank/create$", BankAccountCreateView.as_view(), name="bank_new"), re_path(r"^bank/create$", BankAccountCreateView.as_view(), name="bank_new"),
url( re_path(
r"^bank/(?P<b_account_id>[0-9]+)$", r"^bank/(?P<b_account_id>[0-9]+)$",
BankAccountDetailView.as_view(), BankAccountDetailView.as_view(),
name="bank_details", name="bank_details",
), ),
url( re_path(
r"^bank/(?P<b_account_id>[0-9]+)/edit$", r"^bank/(?P<b_account_id>[0-9]+)/edit$",
BankAccountEditView.as_view(), BankAccountEditView.as_view(),
name="bank_edit", name="bank_edit",
), ),
url( re_path(
r"^bank/(?P<b_account_id>[0-9]+)/delete$", r"^bank/(?P<b_account_id>[0-9]+)/delete$",
BankAccountDeleteView.as_view(), BankAccountDeleteView.as_view(),
name="bank_delete", name="bank_delete",
), ),
# Club accounts # Club accounts
url(r"^club/create$", ClubAccountCreateView.as_view(), name="club_new"), re_path(r"^club/create$", ClubAccountCreateView.as_view(), name="club_new"),
url( re_path(
r"^club/(?P<c_account_id>[0-9]+)$", r"^club/(?P<c_account_id>[0-9]+)$",
ClubAccountDetailView.as_view(), ClubAccountDetailView.as_view(),
name="club_details", name="club_details",
), ),
url( re_path(
r"^club/(?P<c_account_id>[0-9]+)/edit$", r"^club/(?P<c_account_id>[0-9]+)/edit$",
ClubAccountEditView.as_view(), ClubAccountEditView.as_view(),
name="club_edit", name="club_edit",
), ),
url( re_path(
r"^club/(?P<c_account_id>[0-9]+)/delete$", r"^club/(?P<c_account_id>[0-9]+)/delete$",
ClubAccountDeleteView.as_view(), ClubAccountDeleteView.as_view(),
name="club_delete", name="club_delete",
), ),
# Journals # Journals
url(r"^journal/create$", JournalCreateView.as_view(), name="journal_new"), re_path(r"^journal/create$", JournalCreateView.as_view(), name="journal_new"),
url( re_path(
r"^journal/(?P<j_id>[0-9]+)$", r"^journal/(?P<j_id>[0-9]+)$",
JournalDetailView.as_view(), JournalDetailView.as_view(),
name="journal_details", name="journal_details",
), ),
url( re_path(
r"^journal/(?P<j_id>[0-9]+)/edit$", r"^journal/(?P<j_id>[0-9]+)/edit$",
JournalEditView.as_view(), JournalEditView.as_view(),
name="journal_edit", name="journal_edit",
), ),
url( re_path(
r"^journal/(?P<j_id>[0-9]+)/delete$", r"^journal/(?P<j_id>[0-9]+)/delete$",
JournalDeleteView.as_view(), JournalDeleteView.as_view(),
name="journal_delete", name="journal_delete",
), ),
url( re_path(
r"^journal/(?P<j_id>[0-9]+)/statement/nature$", r"^journal/(?P<j_id>[0-9]+)/statement/nature$",
JournalNatureStatementView.as_view(), JournalNatureStatementView.as_view(),
name="journal_nature_statement", name="journal_nature_statement",
), ),
url( re_path(
r"^journal/(?P<j_id>[0-9]+)/statement/person$", r"^journal/(?P<j_id>[0-9]+)/statement/person$",
JournalPersonStatementView.as_view(), JournalPersonStatementView.as_view(),
name="journal_person_statement", name="journal_person_statement",
), ),
url( re_path(
r"^journal/(?P<j_id>[0-9]+)/statement/accounting$", r"^journal/(?P<j_id>[0-9]+)/statement/accounting$",
JournalAccountingStatementView.as_view(), JournalAccountingStatementView.as_view(),
name="journal_accounting_statement", name="journal_accounting_statement",
), ),
# Operations # Operations
url( re_path(
r"^operation/create/(?P<j_id>[0-9]+)$", r"^operation/create/(?P<j_id>[0-9]+)$",
OperationCreateView.as_view(), OperationCreateView.as_view(),
name="op_new", name="op_new",
), ),
url(r"^operation/(?P<op_id>[0-9]+)$", OperationEditView.as_view(), name="op_edit"), re_path(
url( r"^operation/(?P<op_id>[0-9]+)$", OperationEditView.as_view(), name="op_edit"
),
re_path(
r"^operation/(?P<op_id>[0-9]+)/pdf$", OperationPDFView.as_view(), name="op_pdf" r"^operation/(?P<op_id>[0-9]+)/pdf$", OperationPDFView.as_view(), name="op_pdf"
), ),
# Companies # Companies
url(r"^company/list$", CompanyListView.as_view(), name="co_list"), re_path(r"^company/list$", CompanyListView.as_view(), name="co_list"),
url(r"^company/create$", CompanyCreateView.as_view(), name="co_new"), re_path(r"^company/create$", CompanyCreateView.as_view(), name="co_new"),
url(r"^company/(?P<co_id>[0-9]+)$", CompanyEditView.as_view(), name="co_edit"), re_path(r"^company/(?P<co_id>[0-9]+)$", CompanyEditView.as_view(), name="co_edit"),
# Labels # Labels
url(r"^label/new$", LabelCreateView.as_view(), name="label_new"), re_path(r"^label/new$", LabelCreateView.as_view(), name="label_new"),
url( re_path(
r"^label/(?P<clubaccount_id>[0-9]+)$", r"^label/(?P<clubaccount_id>[0-9]+)$",
LabelListView.as_view(), LabelListView.as_view(),
name="label_list", name="label_list",
), ),
url( re_path(
r"^label/(?P<label_id>[0-9]+)/edit$", LabelEditView.as_view(), name="label_edit" r"^label/(?P<label_id>[0-9]+)/edit$", LabelEditView.as_view(), name="label_edit"
), ),
url( re_path(
r"^label/(?P<label_id>[0-9]+)/delete$", r"^label/(?P<label_id>[0-9]+)/delete$",
LabelDeleteView.as_view(), LabelDeleteView.as_view(),
name="label_delete", name="label_delete",
), ),
# User account # User account
url(r"^refound/account$", RefoundAccountView.as_view(), name="refound_account"), re_path(r"^refound/account$", RefoundAccountView.as_view(), name="refound_account"),
] ]

View File

@ -24,7 +24,7 @@
from django.views.generic import ListView, DetailView from django.views.generic import ListView, DetailView
from django.views.generic.edit import UpdateView, CreateView, DeleteView, FormView from django.views.generic.edit import UpdateView, CreateView, DeleteView, FormView
from django.core.urlresolvers import reverse_lazy, reverse from django.urls import reverse_lazy, reverse
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.forms.models import modelform_factory from django.forms.models import modelform_factory
from django.core.exceptions import PermissionDenied, ValidationError from django.core.exceptions import PermissionDenied, ValidationError

View File

@ -22,35 +22,35 @@
# #
# #
from django.conf.urls import url, include from django.urls import re_path, include
from api.views import * from api.views import *
from rest_framework import routers from rest_framework import routers
# Router config # Router config
router = routers.DefaultRouter() router = routers.DefaultRouter()
router.register(r"counter", CounterViewSet, base_name="api_counter") router.register(r"counter", CounterViewSet, basename="api_counter")
router.register(r"user", UserViewSet, base_name="api_user") router.register(r"user", UserViewSet, basename="api_user")
router.register(r"club", ClubViewSet, base_name="api_club") router.register(r"club", ClubViewSet, basename="api_club")
router.register(r"group", GroupViewSet, base_name="api_group") router.register(r"group", GroupViewSet, basename="api_group")
# Launderette # Launderette
router.register( router.register(
r"launderette/place", LaunderettePlaceViewSet, base_name="api_launderette_place" r"launderette/place", LaunderettePlaceViewSet, basename="api_launderette_place"
) )
router.register( router.register(
r"launderette/machine", r"launderette/machine",
LaunderetteMachineViewSet, LaunderetteMachineViewSet,
base_name="api_launderette_machine", basename="api_launderette_machine",
) )
router.register( router.register(
r"launderette/token", LaunderetteTokenViewSet, base_name="api_launderette_token" r"launderette/token", LaunderetteTokenViewSet, basename="api_launderette_token"
) )
urlpatterns = [ urlpatterns = [
# API # API
url(r"^", include(router.urls)), re_path(r"^", include(router.urls)),
url(r"^login/", include("rest_framework.urls", namespace="rest_framework")), re_path(r"^login/", include("rest_framework.urls", namespace="rest_framework")),
url(r"^markdown$", RenderMarkdown, name="api_markdown"), re_path(r"^markdown$", RenderMarkdown, name="api_markdown"),
url(r"^mailings$", FetchMailingLists, name="mailings_fetch"), re_path(r"^mailings$", FetchMailingLists, name="mailings_fetch"),
] ]

View File

@ -25,7 +25,7 @@
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework import viewsets from rest_framework import viewsets
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
from rest_framework.decorators import detail_route from rest_framework.decorators import action
from django.db.models.query import QuerySet from django.db.models.query import QuerySet
from core.views import can_view, can_edit from core.views import can_view, can_edit
@ -46,7 +46,7 @@ def check_if(obj, user, test):
class ManageModelMixin: class ManageModelMixin:
@detail_route() @action(detail=True)
def id(self, request, pk=None): def id(self, request, pk=None):
""" """
Get by id (api/v1/router/{pk}/id/) Get by id (api/v1/router/{pk}/id/)

View File

@ -24,7 +24,7 @@
from rest_framework import serializers from rest_framework import serializers
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.decorators import list_route from rest_framework.decorators import action
from counter.models import Counter from counter.models import Counter
@ -51,7 +51,7 @@ class CounterViewSet(RightModelViewSet):
serializer_class = CounterSerializer serializer_class = CounterSerializer
queryset = Counter.objects.all() queryset = Counter.objects.all()
@list_route() @action(detail=False)
def bar(self, request): def bar(self, request):
""" """
Return all bars (api/v1/counter/bar/) Return all bars (api/v1/counter/bar/)

View File

@ -24,7 +24,7 @@
from rest_framework import serializers from rest_framework import serializers
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.decorators import list_route from rest_framework.decorators import action
from launderette.models import Launderette, Machine, Token from launderette.models import Launderette, Machine, Token
@ -96,7 +96,7 @@ class LaunderetteTokenViewSet(RightModelViewSet):
serializer_class = LaunderetteTokenSerializer serializer_class = LaunderetteTokenSerializer
queryset = Token.objects.all() queryset = Token.objects.all()
@list_route() @action(detail=False)
def washing(self, request): def washing(self, request):
""" """
Return all washing tokens (api/v1/launderette/token/washing) Return all washing tokens (api/v1/launderette/token/washing)
@ -105,7 +105,7 @@ class LaunderetteTokenViewSet(RightModelViewSet):
serializer = self.get_serializer(self.queryset, many=True) serializer = self.get_serializer(self.queryset, many=True)
return Response(serializer.data) return Response(serializer.data)
@list_route() @action(detail=False)
def drying(self, request): def drying(self, request):
""" """
Return all drying tokens (api/v1/launderette/token/drying) Return all drying tokens (api/v1/launderette/token/drying)
@ -114,7 +114,7 @@ class LaunderetteTokenViewSet(RightModelViewSet):
serializer = self.get_serializer(self.queryset, many=True) serializer = self.get_serializer(self.queryset, many=True)
return Response(serializer.data) return Response(serializer.data)
@list_route() @action(detail=False)
def avaliable(self, request): def avaliable(self, request):
""" """
Return all avaliable tokens (api/v1/launderette/token/avaliable) Return all avaliable tokens (api/v1/launderette/token/avaliable)
@ -125,7 +125,7 @@ class LaunderetteTokenViewSet(RightModelViewSet):
serializer = self.get_serializer(self.queryset, many=True) serializer = self.get_serializer(self.queryset, many=True)
return Response(serializer.data) return Response(serializer.data)
@list_route() @action(detail=False)
def unavaliable(self, request): def unavaliable(self, request):
""" """
Return all unavaliable tokens (api/v1/launderette/token/unavaliable) Return all unavaliable tokens (api/v1/launderette/token/unavaliable)

View File

@ -26,7 +26,7 @@ import datetime
from rest_framework import serializers from rest_framework import serializers
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.decorators import list_route from rest_framework.decorators import action
from core.models import User from core.models import User
@ -57,7 +57,7 @@ class UserViewSet(RightModelViewSet):
serializer_class = UserSerializer serializer_class = UserSerializer
queryset = User.objects.filter(is_active=True) queryset = User.objects.filter(is_active=True)
@list_route() @action(detail=False)
def birthday(self, request): def birthday(self, request):
""" """
Return all users born today (api/v1/user/birstdays) Return all users born today (api/v1/user/birstdays)

View File

@ -66,7 +66,7 @@ class MailingForm(forms.Form):
super(MailingForm, self).__init__(*args, **kwargs) super(MailingForm, self).__init__(*args, **kwargs)
self.fields["action"] = forms.TypedChoiceField( self.fields["action"] = forms.TypedChoiceField(
( choices=(
(self.ACTION_NEW_MAILING, _("New Mailing")), (self.ACTION_NEW_MAILING, _("New Mailing")),
(self.ACTION_NEW_SUBSCRIPTION, _("Subscribe")), (self.ACTION_NEW_SUBSCRIPTION, _("Subscribe")),
(self.ACTION_REMOVE_SUBSCRIPTION, _("Remove")), (self.ACTION_REMOVE_SUBSCRIPTION, _("Remove")),
@ -159,13 +159,13 @@ class MailingForm(forms.Form):
class SellingsFormBase(forms.Form): class SellingsFormBase(forms.Form):
begin_date = forms.DateTimeField( begin_date = forms.DateTimeField(
["%Y-%m-%d %H:%M:%S"], input_formats=["%Y-%m-%d %H:%M:%S"],
label=_("Begin date"), label=_("Begin date"),
required=False, required=False,
widget=SelectDateTime, widget=SelectDateTime,
) )
end_date = forms.DateTimeField( end_date = forms.DateTimeField(
["%Y-%m-%d %H:%M:%S"], input_formats=["%Y-%m-%d %H:%M:%S"],
label=_("End date"), label=_("End date"),
required=False, required=False,
widget=SelectDateTime, widget=SelectDateTime,

View File

@ -3,6 +3,7 @@ from __future__ import unicode_literals
from django.db import migrations, models from django.db import migrations, models
import django.core.validators import django.core.validators
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -90,7 +91,10 @@ class Migration(migrations.Migration):
( (
"club", "club",
models.ForeignKey( models.ForeignKey(
verbose_name="club", to="club.Club", related_name="members" verbose_name="club",
to="club.Club",
related_name="members",
on_delete=django.db.models.deletion.CASCADE,
), ),
), ),
], ],

View File

@ -3,6 +3,7 @@ from __future__ import unicode_literals
from django.db import migrations, models from django.db import migrations, models
from django.conf import settings from django.conf import settings
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -18,6 +19,7 @@ class Migration(migrations.Migration):
model_name="membership", model_name="membership",
name="user", name="user",
field=models.ForeignKey( field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
verbose_name="user", verbose_name="user",
to=settings.AUTH_USER_MODEL, to=settings.AUTH_USER_MODEL,
related_name="membership", related_name="membership",
@ -34,6 +36,7 @@ class Migration(migrations.Migration):
model_name="club", model_name="club",
name="home", name="home",
field=models.OneToOneField( field=models.OneToOneField(
on_delete=django.db.models.deletion.CASCADE,
blank=True, blank=True,
null=True, null=True,
related_name="home_of_club", related_name="home_of_club",
@ -45,14 +48,21 @@ class Migration(migrations.Migration):
model_name="club", model_name="club",
name="owner_group", name="owner_group",
field=models.ForeignKey( field=models.ForeignKey(
default=1, to="core.Group", related_name="owned_club" on_delete=django.db.models.deletion.CASCADE,
default=1,
to="core.Group",
related_name="owned_club",
), ),
), ),
migrations.AddField( migrations.AddField(
model_name="club", model_name="club",
name="parent", name="parent",
field=models.ForeignKey( field=models.ForeignKey(
null=True, to="club.Club", related_name="children", blank=True on_delete=django.db.models.deletion.CASCADE,
null=True,
to="club.Club",
related_name="children",
blank=True,
), ),
), ),
migrations.AddField( migrations.AddField(

View File

@ -3,6 +3,7 @@ from __future__ import unicode_literals
from django.db import migrations, models from django.db import migrations, models
from django.conf import settings from django.conf import settings
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -14,6 +15,7 @@ class Migration(migrations.Migration):
model_name="membership", model_name="membership",
name="user", name="user",
field=models.ForeignKey( field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
verbose_name="user", verbose_name="user",
related_name="memberships", related_name="memberships",
to=settings.AUTH_USER_MODEL, to=settings.AUTH_USER_MODEL,

View File

@ -5,6 +5,7 @@ from django.db import migrations, models
from django.conf import settings from django.conf import settings
import re import re
import django.core.validators import django.core.validators
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -51,12 +52,16 @@ class Migration(migrations.Migration):
( (
"club", "club",
models.ForeignKey( models.ForeignKey(
verbose_name="Club", related_name="mailings", to="club.Club" on_delete=django.db.models.deletion.CASCADE,
verbose_name="Club",
related_name="mailings",
to="club.Club",
), ),
), ),
( (
"moderator", "moderator",
models.ForeignKey( models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
null=True, null=True,
verbose_name="moderator", verbose_name="moderator",
related_name="moderated_mailings", related_name="moderated_mailings",
@ -84,6 +89,7 @@ class Migration(migrations.Migration):
( (
"mailing", "mailing",
models.ForeignKey( models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
verbose_name="Mailing", verbose_name="Mailing",
related_name="subscriptions", related_name="subscriptions",
to="club.Mailing", to="club.Mailing",
@ -92,6 +98,7 @@ class Migration(migrations.Migration):
( (
"user", "user",
models.ForeignKey( models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
null=True, null=True,
verbose_name="User", verbose_name="User",
related_name="mailing_subscriptions", related_name="mailing_subscriptions",

View File

@ -5,6 +5,7 @@ from django.db import migrations, models
from club.models import Club from club.models import Club
from core.operations import PsqlRunOnly from core.operations import PsqlRunOnly
import django.db.models.deletion
def generate_club_pages(apps, schema_editor): def generate_club_pages(apps, schema_editor):
@ -31,7 +32,11 @@ class Migration(migrations.Migration):
model_name="club", model_name="club",
name="page", name="page",
field=models.OneToOneField( field=models.OneToOneField(
related_name="club", blank=True, null=True, to="core.Page" on_delete=django.db.models.deletion.CASCADE,
related_name="club",
blank=True,
null=True,
to="core.Page",
), ),
), ),
migrations.AddField( migrations.AddField(

View File

@ -3,6 +3,7 @@ from __future__ import unicode_literals
from django.db import migrations, models from django.db import migrations, models
import club.models import club.models
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -14,6 +15,7 @@ class Migration(migrations.Migration):
model_name="club", model_name="club",
name="owner_group", name="owner_group",
field=models.ForeignKey( field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
default=club.models.Club.get_default_owner_group, default=club.models.Club.get_default_owner_group,
related_name="owned_club", related_name="owned_club",
to="core.Group", to="core.Group",

View File

@ -29,7 +29,7 @@ from django.conf import settings
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.core.exceptions import ValidationError, ObjectDoesNotExist from django.core.exceptions import ValidationError, ObjectDoesNotExist
from django.db import transaction from django.db import transaction
from django.core.urlresolvers import reverse from django.urls import reverse
from django.utils import timezone from django.utils import timezone
from django.core.validators import RegexValidator, validate_email from django.core.validators import RegexValidator, validate_email
from django.utils.functional import cached_property from django.utils.functional import cached_property
@ -46,7 +46,9 @@ class Club(models.Model):
id = models.AutoField(primary_key=True, db_index=True) id = models.AutoField(primary_key=True, db_index=True)
name = models.CharField(_("name"), max_length=64) name = models.CharField(_("name"), max_length=64)
parent = models.ForeignKey("Club", related_name="children", null=True, blank=True) parent = models.ForeignKey(
"Club", related_name="children", null=True, blank=True, on_delete=models.CASCADE
)
unix_name = models.CharField( unix_name = models.CharField(
_("unix name"), _("unix name"),
max_length=30, max_length=30,
@ -75,7 +77,10 @@ class Club(models.Model):
return settings.SITH_GROUP_ROOT_ID return settings.SITH_GROUP_ROOT_ID
owner_group = models.ForeignKey( owner_group = models.ForeignKey(
Group, related_name="owned_club", default=get_default_owner_group Group,
related_name="owned_club",
default=get_default_owner_group,
on_delete=models.CASCADE,
) )
edit_groups = models.ManyToManyField( edit_groups = models.ManyToManyField(
Group, related_name="editable_club", blank=True Group, related_name="editable_club", blank=True
@ -91,7 +96,9 @@ class Club(models.Model):
blank=True, blank=True,
on_delete=models.SET_NULL, on_delete=models.SET_NULL,
) )
page = models.OneToOneField(Page, related_name="club", blank=True, null=True) page = models.OneToOneField(
Page, related_name="club", blank=True, null=True, on_delete=models.CASCADE
)
class Meta: class Meta:
ordering = ["name", "unix_name"] ordering = ["name", "unix_name"]
@ -183,8 +190,8 @@ class Club(models.Model):
name=settings.SITH_MAIN_MEMBERS_GROUP name=settings.SITH_MAIN_MEMBERS_GROUP
).first() ).first()
self.make_home() self.make_home()
self.home.edit_groups = [board] self.home.edit_groups.set([board])
self.home.view_groups = [member, subscribers] self.home.view_groups.set([member, subscribers])
self.home.save() self.home.save()
self.make_page() self.make_page()
@ -261,9 +268,15 @@ class Membership(models.Model):
related_name="memberships", related_name="memberships",
null=False, null=False,
blank=False, blank=False,
on_delete=models.CASCADE,
) )
club = models.ForeignKey( club = models.ForeignKey(
Club, verbose_name=_("club"), related_name="members", null=False, blank=False Club,
verbose_name=_("club"),
related_name="members",
null=False,
blank=False,
on_delete=models.CASCADE,
) )
start_date = models.DateField(_("start date"), default=timezone.now) start_date = models.DateField(_("start date"), default=timezone.now)
end_date = models.DateField(_("end date"), null=True, blank=True) end_date = models.DateField(_("end date"), null=True, blank=True)
@ -317,7 +330,12 @@ class Mailing(models.Model):
""" """
club = models.ForeignKey( club = models.ForeignKey(
Club, verbose_name=_("Club"), related_name="mailings", null=False, blank=False Club,
verbose_name=_("Club"),
related_name="mailings",
null=False,
blank=False,
on_delete=models.CASCADE,
) )
email = models.CharField( email = models.CharField(
_("Email address"), _("Email address"),
@ -334,7 +352,11 @@ class Mailing(models.Model):
) )
is_moderated = models.BooleanField(_("is moderated"), default=False) is_moderated = models.BooleanField(_("is moderated"), default=False)
moderator = models.ForeignKey( moderator = models.ForeignKey(
User, related_name="moderated_mailings", verbose_name=_("moderator"), null=True User,
related_name="moderated_mailings",
verbose_name=_("moderator"),
null=True,
on_delete=models.CASCADE,
) )
def clean(self): def clean(self):
@ -409,6 +431,7 @@ class MailingSubscription(models.Model):
related_name="subscriptions", related_name="subscriptions",
null=False, null=False,
blank=False, blank=False,
on_delete=models.CASCADE,
) )
user = models.ForeignKey( user = models.ForeignKey(
User, User,
@ -416,6 +439,7 @@ class MailingSubscription(models.Model):
related_name="mailing_subscriptions", related_name="mailing_subscriptions",
null=True, null=True,
blank=True, blank=True,
on_delete=models.CASCADE,
) )
email = models.EmailField(_("Email address"), blank=False, null=False) email = models.EmailField(_("Email address"), blank=False, null=False)

View File

@ -26,7 +26,7 @@ from django.conf import settings
from django.test import TestCase from django.test import TestCase
from django.utils import timezone, html from django.utils import timezone, html
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.core.urlresolvers import reverse from django.urls import reverse
from django.core.management import call_command from django.core.management import call_command
from django.core.exceptions import ValidationError, NON_FIELD_ERRORS from django.core.exceptions import ValidationError, NON_FIELD_ERRORS

View File

@ -23,80 +23,88 @@
# #
# #
from django.conf.urls import url from django.urls import re_path
from club.views import * from club.views import *
urlpatterns = [ urlpatterns = [
url(r"^$", ClubListView.as_view(), name="club_list"), re_path(r"^$", ClubListView.as_view(), name="club_list"),
url(r"^new$", ClubCreateView.as_view(), name="club_new"), re_path(r"^new$", ClubCreateView.as_view(), name="club_new"),
url(r"^stats$", ClubStatView.as_view(), name="club_stats"), re_path(r"^stats$", ClubStatView.as_view(), name="club_stats"),
url(r"^(?P<club_id>[0-9]+)/$", ClubView.as_view(), name="club_view"), re_path(r"^(?P<club_id>[0-9]+)/$", ClubView.as_view(), name="club_view"),
url( re_path(
r"^(?P<club_id>[0-9]+)/rev/(?P<rev_id>[0-9]+)/$", r"^(?P<club_id>[0-9]+)/rev/(?P<rev_id>[0-9]+)/$",
ClubRevView.as_view(), ClubRevView.as_view(),
name="club_view_rev", name="club_view_rev",
), ),
url(r"^(?P<club_id>[0-9]+)/hist$", ClubPageHistView.as_view(), name="club_hist"), re_path(
url(r"^(?P<club_id>[0-9]+)/edit$", ClubEditView.as_view(), name="club_edit"), r"^(?P<club_id>[0-9]+)/hist$", ClubPageHistView.as_view(), name="club_hist"
url( ),
re_path(r"^(?P<club_id>[0-9]+)/edit$", ClubEditView.as_view(), name="club_edit"),
re_path(
r"^(?P<club_id>[0-9]+)/edit/page$", r"^(?P<club_id>[0-9]+)/edit/page$",
ClubPageEditView.as_view(), ClubPageEditView.as_view(),
name="club_edit_page", name="club_edit_page",
), ),
url( re_path(
r"^(?P<club_id>[0-9]+)/members$", ClubMembersView.as_view(), name="club_members" r"^(?P<club_id>[0-9]+)/members$", ClubMembersView.as_view(), name="club_members"
), ),
url( re_path(
r"^(?P<club_id>[0-9]+)/elderlies$", r"^(?P<club_id>[0-9]+)/elderlies$",
ClubOldMembersView.as_view(), ClubOldMembersView.as_view(),
name="club_old_members", name="club_old_members",
), ),
url( re_path(
r"^(?P<club_id>[0-9]+)/sellings$", r"^(?P<club_id>[0-9]+)/sellings$",
ClubSellingView.as_view(), ClubSellingView.as_view(),
name="club_sellings", name="club_sellings",
), ),
url( re_path(
r"^(?P<club_id>[0-9]+)/sellings/csv$", r"^(?P<club_id>[0-9]+)/sellings/csv$",
ClubSellingCSVView.as_view(), ClubSellingCSVView.as_view(),
name="sellings_csv", name="sellings_csv",
), ),
url(r"^(?P<club_id>[0-9]+)/prop$", ClubEditPropView.as_view(), name="club_prop"), re_path(
url(r"^(?P<club_id>[0-9]+)/tools$", ClubToolsView.as_view(), name="tools"), r"^(?P<club_id>[0-9]+)/prop$", ClubEditPropView.as_view(), name="club_prop"
url(r"^(?P<club_id>[0-9]+)/mailing$", ClubMailingView.as_view(), name="mailing"), ),
url( re_path(r"^(?P<club_id>[0-9]+)/tools$", ClubToolsView.as_view(), name="tools"),
re_path(
r"^(?P<club_id>[0-9]+)/mailing$", ClubMailingView.as_view(), name="mailing"
),
re_path(
r"^(?P<mailing_id>[0-9]+)/mailing/generate$", r"^(?P<mailing_id>[0-9]+)/mailing/generate$",
MailingAutoGenerationView.as_view(), MailingAutoGenerationView.as_view(),
name="mailing_generate", name="mailing_generate",
), ),
url( re_path(
r"^(?P<mailing_id>[0-9]+)/mailing/delete$", r"^(?P<mailing_id>[0-9]+)/mailing/delete$",
MailingDeleteView.as_view(), MailingDeleteView.as_view(),
name="mailing_delete", name="mailing_delete",
), ),
url( re_path(
r"^(?P<mailing_subscription_id>[0-9]+)/mailing/delete/subscription$", r"^(?P<mailing_subscription_id>[0-9]+)/mailing/delete/subscription$",
MailingSubscriptionDeleteView.as_view(), MailingSubscriptionDeleteView.as_view(),
name="mailing_subscription_delete", name="mailing_subscription_delete",
), ),
url( re_path(
r"^membership/(?P<membership_id>[0-9]+)/set_old$", r"^membership/(?P<membership_id>[0-9]+)/set_old$",
MembershipSetOldView.as_view(), MembershipSetOldView.as_view(),
name="membership_set_old", name="membership_set_old",
), ),
url(r"^(?P<club_id>[0-9]+)/poster$", PosterListView.as_view(), name="poster_list"), re_path(
url( r"^(?P<club_id>[0-9]+)/poster$", PosterListView.as_view(), name="poster_list"
),
re_path(
r"^(?P<club_id>[0-9]+)/poster/create$", r"^(?P<club_id>[0-9]+)/poster/create$",
PosterCreateView.as_view(), PosterCreateView.as_view(),
name="poster_create", name="poster_create",
), ),
url( re_path(
r"^(?P<club_id>[0-9]+)/poster/(?P<poster_id>[0-9]+)/edit$", r"^(?P<club_id>[0-9]+)/poster/(?P<poster_id>[0-9]+)/edit$",
PosterEditView.as_view(), PosterEditView.as_view(),
name="poster_edit", name="poster_edit",
), ),
url( re_path(
r"^(?P<club_id>[0-9]+)/poster/(?P<poster_id>[0-9]+)/delete$", r"^(?P<club_id>[0-9]+)/poster/(?P<poster_id>[0-9]+)/delete$",
PosterDeleteView.as_view(), PosterDeleteView.as_view(),
name="poster_delete", name="poster_delete",

View File

@ -31,7 +31,7 @@ from django.views.generic.edit import DeleteView
from django.views.generic.detail import SingleObjectMixin from django.views.generic.detail import SingleObjectMixin
from django.views.generic.edit import UpdateView, CreateView from django.views.generic.edit import UpdateView, CreateView
from django.http import HttpResponseRedirect, HttpResponse, Http404 from django.http import HttpResponseRedirect, HttpResponse, Http404
from django.core.urlresolvers import reverse, reverse_lazy from django.urls import reverse, reverse_lazy
from django.utils import timezone from django.utils import timezone
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext as _t from django.utils.translation import ugettext as _t

View File

@ -3,6 +3,7 @@ from __future__ import unicode_literals
from django.db import migrations, models from django.db import migrations, models
from django.conf import settings from django.conf import settings
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -50,6 +51,7 @@ class Migration(migrations.Migration):
( (
"author", "author",
models.ForeignKey( models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="owned_news", related_name="owned_news",
to=settings.AUTH_USER_MODEL, to=settings.AUTH_USER_MODEL,
verbose_name="author", verbose_name="author",
@ -58,12 +60,16 @@ class Migration(migrations.Migration):
( (
"club", "club",
models.ForeignKey( models.ForeignKey(
related_name="news", to="club.Club", verbose_name="club" on_delete=django.db.models.deletion.CASCADE,
related_name="news",
to="club.Club",
verbose_name="club",
), ),
), ),
( (
"moderator", "moderator",
models.ForeignKey( models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="moderated_news", related_name="moderated_news",
null=True, null=True,
to=settings.AUTH_USER_MODEL, to=settings.AUTH_USER_MODEL,
@ -99,7 +105,10 @@ class Migration(migrations.Migration):
( (
"news", "news",
models.ForeignKey( models.ForeignKey(
related_name="dates", to="com.News", verbose_name="news_date" on_delete=django.db.models.deletion.CASCADE,
related_name="dates",
to="com.News",
verbose_name="news_date",
), ),
), ),
], ],

View File

@ -3,6 +3,7 @@ from __future__ import unicode_literals
from django.db import migrations, models from django.db import migrations, models
from django.conf import settings from django.conf import settings
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -56,6 +57,7 @@ class Migration(migrations.Migration):
( (
"author", "author",
models.ForeignKey( models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to=settings.AUTH_USER_MODEL, to=settings.AUTH_USER_MODEL,
verbose_name="author", verbose_name="author",
related_name="owned_weekmail_articles", related_name="owned_weekmail_articles",
@ -64,6 +66,7 @@ class Migration(migrations.Migration):
( (
"club", "club",
models.ForeignKey( models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="club.Club", to="club.Club",
verbose_name="club", verbose_name="club",
related_name="weekmail_articles", related_name="weekmail_articles",
@ -72,6 +75,7 @@ class Migration(migrations.Migration):
( (
"weekmail", "weekmail",
models.ForeignKey( models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="com.Weekmail", to="com.Weekmail",
verbose_name="weekmail", verbose_name="weekmail",
related_name="articles", related_name="articles",

View File

@ -4,6 +4,7 @@ from __future__ import unicode_literals
from django.db import migrations, models from django.db import migrations, models
import django.utils.timezone import django.utils.timezone
from django.conf import settings from django.conf import settings
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -48,12 +49,16 @@ class Migration(migrations.Migration):
( (
"club", "club",
models.ForeignKey( models.ForeignKey(
verbose_name="club", related_name="posters", to="club.Club" on_delete=django.db.models.deletion.CASCADE,
verbose_name="club",
related_name="posters",
to="club.Club",
), ),
), ),
( (
"moderator", "moderator",
models.ForeignKey( models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
verbose_name="moderator", verbose_name="moderator",
blank=True, blank=True,
null=True, null=True,

View File

@ -28,7 +28,7 @@ from django.db import models, transaction
from django.db.models import Q from django.db.models import Q
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.utils import timezone from django.utils import timezone
from django.core.urlresolvers import reverse from django.urls import reverse
from django.conf import settings from django.conf import settings
from django.contrib.staticfiles.templatetags.staticfiles import static from django.contrib.staticfiles.templatetags.staticfiles import static
from django.core.mail import EmailMultiAlternatives from django.core.mail import EmailMultiAlternatives
@ -71,13 +71,22 @@ class News(models.Model):
type = models.CharField( type = models.CharField(
_("type"), max_length=16, choices=NEWS_TYPES, default="EVENT" _("type"), max_length=16, choices=NEWS_TYPES, default="EVENT"
) )
club = models.ForeignKey(Club, related_name="news", verbose_name=_("club")) club = models.ForeignKey(
Club, related_name="news", verbose_name=_("club"), on_delete=models.CASCADE
)
author = models.ForeignKey( author = models.ForeignKey(
User, related_name="owned_news", verbose_name=_("author") User,
related_name="owned_news",
verbose_name=_("author"),
on_delete=models.CASCADE,
) )
is_moderated = models.BooleanField(_("is moderated"), default=False) is_moderated = models.BooleanField(_("is moderated"), default=False)
moderator = models.ForeignKey( moderator = models.ForeignKey(
User, related_name="moderated_news", verbose_name=_("moderator"), null=True User,
related_name="moderated_news",
verbose_name=_("moderator"),
null=True,
on_delete=models.CASCADE,
) )
def is_owned_by(self, user): def is_owned_by(self, user):
@ -138,7 +147,12 @@ class NewsDate(models.Model):
we don't have to make copies we don't have to make copies
""" """
news = models.ForeignKey(News, related_name="dates", verbose_name=_("news_date")) news = models.ForeignKey(
News,
related_name="dates",
verbose_name=_("news_date"),
on_delete=models.CASCADE,
)
start_date = models.DateTimeField(_("start_date"), null=True, blank=True) start_date = models.DateTimeField(_("start_date"), null=True, blank=True)
end_date = models.DateTimeField(_("end_date"), null=True, blank=True) end_date = models.DateTimeField(_("end_date"), null=True, blank=True)
@ -230,15 +244,25 @@ class Weekmail(models.Model):
class WeekmailArticle(models.Model): class WeekmailArticle(models.Model):
weekmail = models.ForeignKey( weekmail = models.ForeignKey(
Weekmail, related_name="articles", verbose_name=_("weekmail"), null=True Weekmail,
related_name="articles",
verbose_name=_("weekmail"),
null=True,
on_delete=models.CASCADE,
) )
title = models.CharField(_("title"), max_length=64) title = models.CharField(_("title"), max_length=64)
content = models.TextField(_("content")) content = models.TextField(_("content"))
author = models.ForeignKey( author = models.ForeignKey(
User, related_name="owned_weekmail_articles", verbose_name=_("author") User,
related_name="owned_weekmail_articles",
verbose_name=_("author"),
on_delete=models.CASCADE,
) )
club = models.ForeignKey( club = models.ForeignKey(
Club, related_name="weekmail_articles", verbose_name=_("club") Club,
related_name="weekmail_articles",
verbose_name=_("club"),
on_delete=models.CASCADE,
) )
rank = models.IntegerField(_("rank"), default=-1) rank = models.IntegerField(_("rank"), default=-1)
@ -271,7 +295,11 @@ class Poster(models.Model):
) )
file = models.ImageField(_("file"), null=False, upload_to="com/posters") file = models.ImageField(_("file"), null=False, upload_to="com/posters")
club = models.ForeignKey( club = models.ForeignKey(
Club, related_name="posters", verbose_name=_("club"), null=False Club,
related_name="posters",
verbose_name=_("club"),
null=False,
on_delete=models.CASCADE,
) )
screens = models.ManyToManyField(Screen, related_name="posters") screens = models.ManyToManyField(Screen, related_name="posters")
date_begin = models.DateTimeField(blank=False, null=False, default=timezone.now) date_begin = models.DateTimeField(blank=False, null=False, default=timezone.now)
@ -286,6 +314,7 @@ class Poster(models.Model):
verbose_name=_("moderator"), verbose_name=_("moderator"),
null=True, null=True,
blank=True, blank=True,
on_delete=models.CASCADE,
) )
def save(self, *args, **kwargs): def save(self, *args, **kwargs):

View File

@ -24,7 +24,7 @@
from django.test import TestCase from django.test import TestCase
from django.conf import settings from django.conf import settings
from django.core.urlresolvers import reverse from django.urls import reverse
from django.core.management import call_command from django.core.management import call_command
from django.utils import html from django.utils import html
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
@ -62,7 +62,7 @@ class ComTest(TestCase):
self.com_group = RealGroup.objects.filter( self.com_group = RealGroup.objects.filter(
id=settings.SITH_GROUP_COM_ADMIN_ID id=settings.SITH_GROUP_COM_ADMIN_ID
).first() ).first()
self.skia.groups = [self.com_group] self.skia.groups.set([self.com_group])
self.skia.save() self.skia.save()
self.client.login(username=self.skia.username, password="plop") self.client.login(username=self.skia.username, password="plop")

View File

@ -22,97 +22,103 @@
# #
# #
from django.conf.urls import url from django.urls import re_path
from com.views import * from com.views import *
from club.views import MailingDeleteView from club.views import MailingDeleteView
urlpatterns = [ urlpatterns = [
url(r"^sith/edit/alert$", AlertMsgEditView.as_view(), name="alert_edit"), re_path(r"^sith/edit/alert$", AlertMsgEditView.as_view(), name="alert_edit"),
url(r"^sith/edit/info$", InfoMsgEditView.as_view(), name="info_edit"), re_path(r"^sith/edit/info$", InfoMsgEditView.as_view(), name="info_edit"),
url( re_path(
r"^sith/edit/weekmail_destinations$", r"^sith/edit/weekmail_destinations$",
WeekmailDestinationEditView.as_view(), WeekmailDestinationEditView.as_view(),
name="weekmail_destinations", name="weekmail_destinations",
), ),
url(r"^weekmail$", WeekmailEditView.as_view(), name="weekmail"), re_path(r"^weekmail$", WeekmailEditView.as_view(), name="weekmail"),
url(r"^weekmail/preview$", WeekmailPreviewView.as_view(), name="weekmail_preview"), re_path(
url( r"^weekmail/preview$", WeekmailPreviewView.as_view(), name="weekmail_preview"
),
re_path(
r"^weekmail/new_article$", r"^weekmail/new_article$",
WeekmailArticleCreateView.as_view(), WeekmailArticleCreateView.as_view(),
name="weekmail_article", name="weekmail_article",
), ),
url( re_path(
r"^weekmail/article/(?P<article_id>[0-9]+)/delete$", r"^weekmail/article/(?P<article_id>[0-9]+)/delete$",
WeekmailArticleDeleteView.as_view(), WeekmailArticleDeleteView.as_view(),
name="weekmail_article_delete", name="weekmail_article_delete",
), ),
url( re_path(
r"^weekmail/article/(?P<article_id>[0-9]+)/edit$", r"^weekmail/article/(?P<article_id>[0-9]+)/edit$",
WeekmailArticleEditView.as_view(), WeekmailArticleEditView.as_view(),
name="weekmail_article_edit", name="weekmail_article_edit",
), ),
url(r"^news$", NewsListView.as_view(), name="news_list"), re_path(r"^news$", NewsListView.as_view(), name="news_list"),
url(r"^news/admin$", NewsAdminListView.as_view(), name="news_admin_list"), re_path(r"^news/admin$", NewsAdminListView.as_view(), name="news_admin_list"),
url(r"^news/create$", NewsCreateView.as_view(), name="news_new"), re_path(r"^news/create$", NewsCreateView.as_view(), name="news_new"),
url( re_path(
r"^news/(?P<news_id>[0-9]+)/delete$", r"^news/(?P<news_id>[0-9]+)/delete$",
NewsDeleteView.as_view(), NewsDeleteView.as_view(),
name="news_delete", name="news_delete",
), ),
url( re_path(
r"^news/(?P<news_id>[0-9]+)/moderate$", r"^news/(?P<news_id>[0-9]+)/moderate$",
NewsModerateView.as_view(), NewsModerateView.as_view(),
name="news_moderate", name="news_moderate",
), ),
url(r"^news/(?P<news_id>[0-9]+)/edit$", NewsEditView.as_view(), name="news_edit"), re_path(
url(r"^news/(?P<news_id>[0-9]+)$", NewsDetailView.as_view(), name="news_detail"), r"^news/(?P<news_id>[0-9]+)/edit$", NewsEditView.as_view(), name="news_edit"
url(r"^mailings$", MailingListAdminView.as_view(), name="mailing_admin"), ),
url( re_path(
r"^news/(?P<news_id>[0-9]+)$", NewsDetailView.as_view(), name="news_detail"
),
re_path(r"^mailings$", MailingListAdminView.as_view(), name="mailing_admin"),
re_path(
r"^mailings/(?P<mailing_id>[0-9]+)/moderate$", r"^mailings/(?P<mailing_id>[0-9]+)/moderate$",
MailingModerateView.as_view(), MailingModerateView.as_view(),
name="mailing_moderate", name="mailing_moderate",
), ),
url( re_path(
r"^mailings/(?P<mailing_id>[0-9]+)/delete$", r"^mailings/(?P<mailing_id>[0-9]+)/delete$",
MailingDeleteView.as_view(redirect_page="com:mailing_admin"), MailingDeleteView.as_view(redirect_page="com:mailing_admin"),
name="mailing_delete", name="mailing_delete",
), ),
url(r"^poster$", PosterListView.as_view(), name="poster_list"), re_path(r"^poster$", PosterListView.as_view(), name="poster_list"),
url(r"^poster/create$", PosterCreateView.as_view(), name="poster_create"), re_path(r"^poster/create$", PosterCreateView.as_view(), name="poster_create"),
url( re_path(
r"^poster/(?P<poster_id>[0-9]+)/edit$", r"^poster/(?P<poster_id>[0-9]+)/edit$",
PosterEditView.as_view(), PosterEditView.as_view(),
name="poster_edit", name="poster_edit",
), ),
url( re_path(
r"^poster/(?P<poster_id>[0-9]+)/delete$", r"^poster/(?P<poster_id>[0-9]+)/delete$",
PosterDeleteView.as_view(), PosterDeleteView.as_view(),
name="poster_delete", name="poster_delete",
), ),
url( re_path(
r"^poster/moderate$", r"^poster/moderate$",
PosterModerateListView.as_view(), PosterModerateListView.as_view(),
name="poster_moderate_list", name="poster_moderate_list",
), ),
url( re_path(
r"^poster/(?P<object_id>[0-9]+)/moderate$", r"^poster/(?P<object_id>[0-9]+)/moderate$",
PosterModerateView.as_view(), PosterModerateView.as_view(),
name="poster_moderate", name="poster_moderate",
), ),
url(r"^screen$", ScreenListView.as_view(), name="screen_list"), re_path(r"^screen$", ScreenListView.as_view(), name="screen_list"),
url(r"^screen/create$", ScreenCreateView.as_view(), name="screen_create"), re_path(r"^screen/create$", ScreenCreateView.as_view(), name="screen_create"),
url( re_path(
r"^screen/(?P<screen_id>[0-9]+)/slideshow$", r"^screen/(?P<screen_id>[0-9]+)/slideshow$",
ScreenSlideshowView.as_view(), ScreenSlideshowView.as_view(),
name="screen_slideshow", name="screen_slideshow",
), ),
url( re_path(
r"^screen/(?P<screen_id>[0-9]+)/edit$", r"^screen/(?P<screen_id>[0-9]+)/edit$",
ScreenEditView.as_view(), ScreenEditView.as_view(),
name="screen_edit", name="screen_edit",
), ),
url( re_path(
r"^screen/(?P<screen_id>[0-9]+)/delete$", r"^screen/(?P<screen_id>[0-9]+)/delete$",
ScreenDeleteView.as_view(), ScreenDeleteView.as_view(),
name="screen_delete", name="screen_delete",

View File

@ -29,7 +29,7 @@ from django.views.generic import ListView, DetailView, View
from django.views.generic.edit import UpdateView, CreateView, DeleteView from django.views.generic.edit import UpdateView, CreateView, DeleteView
from django.views.generic.detail import SingleObjectMixin from django.views.generic.detail import SingleObjectMixin
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.core.urlresolvers import reverse, reverse_lazy from django.urls import reverse, reverse_lazy
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.utils import timezone from django.utils import timezone
from django.conf import settings from django.conf import settings
@ -74,14 +74,14 @@ class PosterForm(forms.ModelForm):
widgets = {"screens": forms.CheckboxSelectMultiple} widgets = {"screens": forms.CheckboxSelectMultiple}
date_begin = forms.DateTimeField( date_begin = forms.DateTimeField(
["%Y-%m-%d %H:%M:%S"], input_formats=["%Y-%m-%d %H:%M:%S"],
label=_("Start date"), label=_("Start date"),
widget=SelectDateTime, widget=SelectDateTime,
required=True, required=True,
initial=timezone.now().strftime("%Y-%m-%d %H:%M:%S"), initial=timezone.now().strftime("%Y-%m-%d %H:%M:%S"),
) )
date_end = forms.DateTimeField( date_end = forms.DateTimeField(
["%Y-%m-%d %H:%M:%S"], input_formats=["%Y-%m-%d %H:%M:%S"],
label=_("End date"), label=_("End date"),
widget=SelectDateTime, widget=SelectDateTime,
required=False, required=False,
@ -200,19 +200,22 @@ class NewsForm(forms.ModelForm):
} }
start_date = forms.DateTimeField( start_date = forms.DateTimeField(
["%Y-%m-%d %H:%M:%S"], input_formats=["%Y-%m-%d %H:%M:%S"],
label=_("Start date"), label=_("Start date"),
widget=SelectDateTime, widget=SelectDateTime,
required=False, required=False,
) )
end_date = forms.DateTimeField( end_date = forms.DateTimeField(
["%Y-%m-%d %H:%M:%S"], input_formats=["%Y-%m-%d %H:%M:%S"],
label=_("End date"), label=_("End date"),
widget=SelectDateTime, widget=SelectDateTime,
required=False, required=False,
) )
until = forms.DateTimeField( until = forms.DateTimeField(
["%Y-%m-%d %H:%M:%S"], label=_("Until"), widget=SelectDateTime, required=False input_formats=["%Y-%m-%d %H:%M:%S"],
label=_("Until"),
widget=SelectDateTime,
required=False,
) )
automoderation = forms.BooleanField(label=_("Automoderation"), required=False) automoderation = forms.BooleanField(label=_("Automoderation"), required=False)

View File

@ -142,18 +142,18 @@ class Command(BaseCommand):
g.save() g.save()
c = Counter(id=b[0], name=b[1], club=bar_club, type="BAR") c = Counter(id=b[0], name=b[1], club=bar_club, type="BAR")
c.save() c.save()
c.edit_groups = [g] g.editable_counters.add(c)
c.save() g.save()
self.reset_index("counter") self.reset_index("counter")
Counter(name="Eboutic", club=main_club, type="EBOUTIC").save() Counter(name="Eboutic", club=main_club, type="EBOUTIC").save()
Counter(name="AE", club=main_club, type="OFFICE").save() Counter(name="AE", club=main_club, type="OFFICE").save()
home_root.view_groups = [ home_root.view_groups.set(
Group.objects.filter(name=settings.SITH_MAIN_MEMBERS_GROUP).first() [Group.objects.filter(name=settings.SITH_MAIN_MEMBERS_GROUP).first()]
] )
club_root.view_groups = [ club_root.view_groups.set(
Group.objects.filter(name=settings.SITH_MAIN_MEMBERS_GROUP).first() [Group.objects.filter(name=settings.SITH_MAIN_MEMBERS_GROUP).first()]
] )
home_root.save() home_root.save()
club_root.save() club_root.save()
@ -163,7 +163,7 @@ class Command(BaseCommand):
p = Page(name="Index") p = Page(name="Index")
p.set_lock(root) p.set_lock(root)
p.save() p.save()
p.view_groups = [settings.SITH_GROUP_PUBLIC_ID] p.view_groups.set([settings.SITH_GROUP_PUBLIC_ID])
p.set_lock(root) p.set_lock(root)
p.save() p.save()
PageRev( PageRev(
@ -178,7 +178,7 @@ Welcome to the wiki page!
p = Page(name="services") p = Page(name="services")
p.set_lock(root) p.set_lock(root)
p.save() p.save()
p.view_groups = [settings.SITH_GROUP_PUBLIC_ID] p.view_groups.set([settings.SITH_GROUP_PUBLIC_ID])
p.set_lock(root) p.set_lock(root)
PageRev( PageRev(
page=p, page=p,
@ -297,9 +297,13 @@ Welcome to the wiki page!
counter.view_groups = [ counter.view_groups = [
Group.objects.filter(name=settings.SITH_MAIN_MEMBERS_GROUP).first().id Group.objects.filter(name=settings.SITH_MAIN_MEMBERS_GROUP).first().id
] ]
counter.groups = [ counter.groups.set(
Group.objects.filter(id=settings.SITH_GROUP_COUNTER_ADMIN_ID).first().id [
Group.objects.filter(id=settings.SITH_GROUP_COUNTER_ADMIN_ID)
.first()
.id
] ]
)
counter.save() counter.save()
# Adding user Comptable # Adding user Comptable
comptable = User( comptable = User(
@ -316,11 +320,13 @@ Welcome to the wiki page!
comptable.view_groups = [ comptable.view_groups = [
Group.objects.filter(name=settings.SITH_MAIN_MEMBERS_GROUP).first().id Group.objects.filter(name=settings.SITH_MAIN_MEMBERS_GROUP).first().id
] ]
comptable.groups = [ comptable.groups.set(
[
Group.objects.filter(id=settings.SITH_GROUP_ACCOUNTING_ADMIN_ID) Group.objects.filter(id=settings.SITH_GROUP_ACCOUNTING_ADMIN_ID)
.first() .first()
.id .id
] ]
)
comptable.save() comptable.save()
# Adding user Guy # Adding user Guy
u = User( u = User(
@ -359,11 +365,11 @@ Welcome to the wiki page!
PageRev( PageRev(
page=p, title="Aide sur la syntaxe", author=skia, content=rm.read() page=p, title="Aide sur la syntaxe", author=skia, content=rm.read()
).save() ).save()
p.view_groups = [settings.SITH_GROUP_PUBLIC_ID] p.view_groups.set([settings.SITH_GROUP_PUBLIC_ID])
p.save(force_lock=True) p.save(force_lock=True)
p = Page(name="Services") p = Page(name="Services")
p.save(force_lock=True) p.save(force_lock=True)
p.view_groups = [settings.SITH_GROUP_PUBLIC_ID] p.view_groups.set([settings.SITH_GROUP_PUBLIC_ID])
p.save(force_lock=True) p.save(force_lock=True)
PageRev( PageRev(
page=p, page=p,
@ -842,9 +848,9 @@ Welcome to the wiki page!
) )
comunity.set_password("plop") comunity.set_password("plop")
comunity.save() comunity.save()
comunity.groups = [ comunity.groups.set(
Group.objects.filter(name="Communication admin").first().id [Group.objects.filter(name="Communication admin").first().id]
] )
comunity.save() comunity.save()
Membership( Membership(
user=comunity, user=comunity,
@ -862,7 +868,7 @@ Welcome to the wiki page!
) )
tutu.set_password("plop") tutu.set_password("plop")
tutu.save() tutu.save()
tutu.groups = [settings.SITH_GROUP_PEDAGOGY_ADMIN_ID] tutu.groups.set([settings.SITH_GROUP_PEDAGOGY_ADMIN_ID])
tutu.save() tutu.save()
# Adding subscription for sli # Adding subscription for sli

View File

@ -25,7 +25,7 @@
import os import os
import re import re
from mistune import Renderer, InlineGrammar, InlineLexer, Markdown, escape, escape_link from mistune import Renderer, InlineGrammar, InlineLexer, Markdown, escape, escape_link
from django.core.urlresolvers import reverse from django.urls import reverse
class SithRenderer(Renderer): class SithRenderer(Renderer):

View File

@ -37,7 +37,7 @@ AnonymousUser = getattr(importlib.import_module(module), klass)
def get_cached_user(request): def get_cached_user(request):
if not hasattr(request, "_cached_user"): if not hasattr(request, "_cached_user"):
user = get_user(request) user = get_user(request)
if user.is_anonymous(): if user.is_anonymous:
user = AnonymousUser(request) user = AnonymousUser(request)
request._cached_user = user request._cached_user = user

View File

@ -8,6 +8,7 @@ import django.core.validators
import core.models import core.models
import phonenumber_field.modelfields import phonenumber_field.modelfields
from django.conf import settings from django.conf import settings
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -276,6 +277,7 @@ class Migration(migrations.Migration):
( (
"group_ptr", "group_ptr",
models.OneToOneField( models.OneToOneField(
on_delete=django.db.models.deletion.CASCADE,
primary_key=True, primary_key=True,
parent_link=True, parent_link=True,
serialize=False, serialize=False,
@ -329,6 +331,7 @@ class Migration(migrations.Migration):
( (
"owner_group", "owner_group",
models.ForeignKey( models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
default=1, default=1,
related_name="owned_page", related_name="owned_page",
verbose_name="owner group", verbose_name="owner group",
@ -390,10 +393,19 @@ class Migration(migrations.Migration):
( (
"author", "author",
models.ForeignKey( models.ForeignKey(
to=settings.AUTH_USER_MODEL, related_name="page_rev" on_delete=django.db.models.deletion.CASCADE,
to=settings.AUTH_USER_MODEL,
related_name="page_rev",
),
),
(
"page",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="core.Page",
related_name="revisions",
), ),
), ),
("page", models.ForeignKey(to="core.Page", related_name="revisions")),
], ],
options={"ordering": ["date"]}, options={"ordering": ["date"]},
), ),
@ -420,7 +432,9 @@ class Migration(migrations.Migration):
( (
"user", "user",
models.OneToOneField( models.OneToOneField(
to=settings.AUTH_USER_MODEL, related_name="preferences" on_delete=django.db.models.deletion.CASCADE,
to=settings.AUTH_USER_MODEL,
related_name="preferences",
), ),
), ),
], ],
@ -469,6 +483,7 @@ class Migration(migrations.Migration):
( (
"owner", "owner",
models.ForeignKey( models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
verbose_name="owner", verbose_name="owner",
to=settings.AUTH_USER_MODEL, to=settings.AUTH_USER_MODEL,
related_name="owned_files", related_name="owned_files",
@ -477,6 +492,7 @@ class Migration(migrations.Migration):
( (
"parent", "parent",
models.ForeignKey( models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
null=True, null=True,
related_name="children", related_name="children",
verbose_name="parent", verbose_name="parent",
@ -512,6 +528,7 @@ class Migration(migrations.Migration):
model_name="user", model_name="user",
name="home", name="home",
field=models.OneToOneField( field=models.OneToOneField(
on_delete=django.db.models.deletion.CASCADE,
blank=True, blank=True,
null=True, null=True,
related_name="home_of", related_name="home_of",

View File

@ -3,6 +3,7 @@ from __future__ import unicode_literals
from django.db import migrations, models from django.db import migrations, models
from django.conf import settings from django.conf import settings
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -21,6 +22,7 @@ class Migration(migrations.Migration):
model_name="page", model_name="page",
name="lock_user", name="lock_user",
field=models.ForeignKey( field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
verbose_name="lock user", verbose_name="lock user",
default=None, default=None,
blank=True, blank=True,

View File

@ -4,6 +4,7 @@ from __future__ import unicode_literals
from django.db import migrations, models from django.db import migrations, models
from django.conf import settings from django.conf import settings
import django.utils.timezone import django.utils.timezone
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -48,7 +49,9 @@ class Migration(migrations.Migration):
( (
"user", "user",
models.ForeignKey( models.ForeignKey(
related_name="notifications", to=settings.AUTH_USER_MODEL on_delete=django.db.models.deletion.CASCADE,
related_name="notifications",
to=settings.AUTH_USER_MODEL,
), ),
), ),
], ],

View File

@ -3,6 +3,7 @@ from __future__ import unicode_literals
from django.db import migrations, models from django.db import migrations, models
from django.conf import settings from django.conf import settings
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -14,6 +15,7 @@ class Migration(migrations.Migration):
model_name="sithfile", model_name="sithfile",
name="moderator", name="moderator",
field=models.ForeignKey( field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="moderated_files", related_name="moderated_files",
verbose_name="owner", verbose_name="owner",
default=0, default=0,

View File

@ -3,6 +3,7 @@ from __future__ import unicode_literals
from django.db import migrations, models from django.db import migrations, models
from django.conf import settings from django.conf import settings
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -14,6 +15,7 @@ class Migration(migrations.Migration):
model_name="sithfile", model_name="sithfile",
name="moderator", name="moderator",
field=models.ForeignKey( field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="moderated_files", related_name="moderated_files",
blank=True, blank=True,
null=True, null=True,

View File

@ -3,6 +3,7 @@ from __future__ import unicode_literals
from django.db import migrations, models from django.db import migrations, models
from django.conf import settings from django.conf import settings
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -35,7 +36,9 @@ class Migration(migrations.Migration):
model_name="preferences", model_name="preferences",
name="user", name="user",
field=models.OneToOneField( field=models.OneToOneField(
related_name="_preferences", to=settings.AUTH_USER_MODEL on_delete=django.db.models.deletion.CASCADE,
related_name="_preferences",
to=settings.AUTH_USER_MODEL,
), ),
), ),
] ]

View File

@ -4,6 +4,7 @@ from __future__ import unicode_literals
from django.db import migrations, models from django.db import migrations, models
from django.conf import settings from django.conf import settings
import django.utils.timezone import django.utils.timezone
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -33,7 +34,9 @@ class Migration(migrations.Migration):
( (
"user", "user",
models.ForeignKey( models.ForeignKey(
related_name="gifts", to=settings.AUTH_USER_MODEL on_delete=django.db.models.deletion.CASCADE,
related_name="gifts",
to=settings.AUTH_USER_MODEL,
), ),
), ),
], ],

View File

@ -3,6 +3,7 @@ from __future__ import unicode_literals
from django.db import migrations, models from django.db import migrations, models
import core.models import core.models
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -14,6 +15,7 @@ class Migration(migrations.Migration):
model_name="page", model_name="page",
name="owner_group", name="owner_group",
field=models.ForeignKey( field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
verbose_name="owner group", verbose_name="owner group",
default=core.models.Page.get_default_owner_group, default=core.models.Page.get_default_owner_group,
related_name="owned_page", related_name="owned_page",

View File

@ -0,0 +1,27 @@
# Generated by Django 2.2.6 on 2019-10-05 22:49
import django.contrib.auth.models
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [("core", "0032_auto_20190909_0043")]
operations = [
migrations.AlterModelOptions(
name="page",
options={
"permissions": (
(
"change_prop_page",
"Can change the page's properties (groups, ...)",
),
)
},
),
migrations.AlterModelManagers(
name="group",
managers=[("objects", django.contrib.auth.models.GroupManager())],
),
]

View File

@ -38,7 +38,7 @@ from django.utils.translation import ugettext_lazy as _
from django.utils import timezone from django.utils import timezone
from django.core import validators from django.core import validators
from django.core.exceptions import ValidationError, PermissionDenied from django.core.exceptions import ValidationError, PermissionDenied
from django.core.urlresolvers import reverse from django.urls import reverse
from django.conf import settings from django.conf import settings
from django.db import transaction from django.db import transaction
from django.contrib.staticfiles.storage import staticfiles_storage from django.contrib.staticfiles.storage import staticfiles_storage
@ -743,7 +743,9 @@ class AnonymousUser(AuthAnonymousUser):
class Preferences(models.Model): class Preferences(models.Model):
user = models.OneToOneField(User, related_name="_preferences") user = models.OneToOneField(
User, related_name="_preferences", on_delete=models.CASCADE
)
receive_weekmail = models.BooleanField( receive_weekmail = models.BooleanField(
_("do you want to receive the weekmail"), default=False _("do you want to receive the weekmail"), default=False
) )
@ -777,7 +779,12 @@ def get_thumbnail_directory(instance, filename):
class SithFile(models.Model): class SithFile(models.Model):
name = models.CharField(_("file name"), max_length=256, blank=False) name = models.CharField(_("file name"), max_length=256, blank=False)
parent = models.ForeignKey( parent = models.ForeignKey(
"self", related_name="children", verbose_name=_("parent"), null=True, blank=True "self",
related_name="children",
verbose_name=_("parent"),
null=True,
blank=True,
on_delete=models.CASCADE,
) )
file = models.FileField( file = models.FileField(
upload_to=get_directory, upload_to=get_directory,
@ -800,7 +807,12 @@ class SithFile(models.Model):
null=True, null=True,
blank=True, blank=True,
) )
owner = models.ForeignKey(User, related_name="owned_files", verbose_name=_("owner")) owner = models.ForeignKey(
User,
related_name="owned_files",
verbose_name=_("owner"),
on_delete=models.CASCADE,
)
edit_groups = models.ManyToManyField( edit_groups = models.ManyToManyField(
Group, related_name="editable_files", verbose_name=_("edit group"), blank=True Group, related_name="editable_files", verbose_name=_("edit group"), blank=True
) )
@ -818,6 +830,7 @@ class SithFile(models.Model):
verbose_name=_("owner"), verbose_name=_("owner"),
null=True, null=True,
blank=True, blank=True,
on_delete=models.CASCADE,
) )
asked_for_removal = models.BooleanField(_("asked for removal"), default=False) asked_for_removal = models.BooleanField(_("asked for removal"), default=False)
is_in_sas = models.BooleanField( is_in_sas = models.BooleanField(
@ -935,8 +948,8 @@ class SithFile(models.Model):
def copy_rights(self): def copy_rights(self):
"""Copy, if possible, the rights of the parent folder""" """Copy, if possible, the rights of the parent folder"""
if self.parent is not None: if self.parent is not None:
self.edit_groups = self.parent.edit_groups.all() self.edit_groups.set(self.parent.edit_groups.all())
self.view_groups = self.parent.view_groups.all() self.view_groups.set(self.parent.view_groups.all())
self.save() self.save()
def move_to(self, parent): def move_to(self, parent):
@ -1133,6 +1146,7 @@ class Page(models.Model):
related_name="owned_page", related_name="owned_page",
verbose_name=_("owner group"), verbose_name=_("owner group"),
default=get_default_owner_group, default=get_default_owner_group,
on_delete=models.CASCADE,
) )
edit_groups = models.ManyToManyField( edit_groups = models.ManyToManyField(
Group, related_name="editable_page", verbose_name=_("edit group"), blank=True Group, related_name="editable_page", verbose_name=_("edit group"), blank=True
@ -1147,6 +1161,7 @@ class Page(models.Model):
blank=True, blank=True,
null=True, null=True,
default=None, default=None,
on_delete=models.CASCADE,
) )
lock_timeout = models.DateTimeField( lock_timeout = models.DateTimeField(
_("lock_timeout"), null=True, blank=True, default=None _("lock_timeout"), null=True, blank=True, default=None
@ -1156,7 +1171,6 @@ class Page(models.Model):
unique_together = ("name", "parent") unique_together = ("name", "parent")
permissions = ( permissions = (
("change_prop_page", "Can change the page's properties (groups, ...)"), ("change_prop_page", "Can change the page's properties (groups, ...)"),
("view_page", "Can view the page"),
) )
@staticmethod @staticmethod
@ -1347,8 +1361,8 @@ class PageRev(models.Model):
title = models.CharField(_("page title"), max_length=255, blank=True) title = models.CharField(_("page title"), max_length=255, blank=True)
content = models.TextField(_("page content"), blank=True) content = models.TextField(_("page content"), blank=True)
date = models.DateTimeField(_("date"), auto_now=True) date = models.DateTimeField(_("date"), auto_now=True)
author = models.ForeignKey(User, related_name="page_rev") author = models.ForeignKey(User, related_name="page_rev", on_delete=models.CASCADE)
page = models.ForeignKey(Page, related_name="revisions") page = models.ForeignKey(Page, related_name="revisions", on_delete=models.CASCADE)
class Meta: class Meta:
ordering = ["date"] ordering = ["date"]
@ -1386,7 +1400,9 @@ class PageRev(models.Model):
class Notification(models.Model): class Notification(models.Model):
user = models.ForeignKey(User, related_name="notifications") user = models.ForeignKey(
User, related_name="notifications", on_delete=models.CASCADE
)
url = models.CharField(_("url"), max_length=255) url = models.CharField(_("url"), max_length=255)
param = models.CharField(_("param"), max_length=128, default="") param = models.CharField(_("param"), max_length=128, default="")
type = models.CharField( type = models.CharField(
@ -1422,7 +1438,7 @@ class Notification(models.Model):
class Gift(models.Model): class Gift(models.Model):
label = models.CharField(_("label"), max_length=255) label = models.CharField(_("label"), max_length=255)
date = models.DateTimeField(_("date"), default=timezone.now) date = models.DateTimeField(_("date"), default=timezone.now)
user = models.ForeignKey(User, related_name="gifts") user = models.ForeignKey(User, related_name="gifts", on_delete=models.CASCADE)
def __str__(self): def __str__(self):
return "%s - %s" % (self.translated_label, self.date.strftime("%d %b %Y")) return "%s - %s" % (self.translated_label, self.date.strftime("%d %b %Y"))

View File

@ -39,7 +39,7 @@
</div> </div>
<header> <header>
{% if not user.is_authenticated() %} {% if not user.is_authenticated %}
<div id="header_logo" style="background-image: url('{{ static('core/img/logo.png') }}'); width: 185px; height: 100px;"> <div id="header_logo" style="background-image: url('{{ static('core/img/logo.png') }}'); width: 185px; height: 100px;">
<a href="{{ url('core:index') }}"></a> <a href="{{ url('core:index') }}"></a>
</div> </div>

View File

@ -11,7 +11,7 @@
{% endif %} {% endif %}
{% if next %} {% if next %}
{% if user.is_authenticated() %} {% if user.is_authenticated %}
<p>{% trans %}Your account doesn't have access to this page. To proceed, <p>{% trans %}Your account doesn't have access to this page. To proceed,
please login with an account that has access.{% endtrans %}</p> please login with an account that has access.{% endtrans %}</p>
{% else %} {% else %}

View File

@ -25,7 +25,7 @@
import os import os
from django.test import Client, TestCase from django.test import Client, TestCase
from django.core.urlresolvers import reverse from django.urls import reverse
from django.core.management import call_command from django.core.management import call_command
from core.models import User, Group, Page from core.models import User, Group, Page

View File

@ -23,189 +23,209 @@
# #
# #
from django.conf.urls import url from django.urls import re_path
from core.views import * from core.views import *
urlpatterns = [ urlpatterns = [
url(r"^$", index, name="index"), re_path(r"^$", index, name="index"),
url(r"^to_markdown$", ToMarkdownView.as_view(), name="to_markdown"), re_path(r"^to_markdown$", ToMarkdownView.as_view(), name="to_markdown"),
url(r"^notifications$", NotificationList.as_view(), name="notification_list"), re_path(r"^notifications$", NotificationList.as_view(), name="notification_list"),
url(r"^notification/(?P<notif_id>[0-9]+)$", notification, name="notification"), re_path(r"^notification/(?P<notif_id>[0-9]+)$", notification, name="notification"),
# Search # Search
url(r"^search/$", search_view, name="search"), re_path(r"^search/$", search_view, name="search"),
url(r"^search_json/$", search_json, name="search_json"), re_path(r"^search_json/$", search_json, name="search_json"),
url(r"^search_user/$", search_user_json, name="search_user"), re_path(r"^search_user/$", search_user_json, name="search_user"),
# Login and co # Login and co
url(r"^login/$", login, name="login"), re_path(r"^login/$", SithLoginView.as_view(), name="login"),
url(r"^logout/$", logout, name="logout"), re_path(r"^logout/$", logout, name="logout"),
url(r"^password_change/$", password_change, name="password_change"), re_path(
url( r"^password_change/$", SithPasswordChangeView.as_view(), name="password_change"
),
re_path(
r"^password_change/(?P<user_id>[0-9]+)$", r"^password_change/(?P<user_id>[0-9]+)$",
password_root_change, password_root_change,
name="password_root_change", name="password_root_change",
), ),
url(r"^password_change/done$", password_change_done, name="password_change_done"), re_path(
url(r"^password_reset/$", password_reset, name="password_reset"), r"^password_change/done$",
url(r"^password_reset/done$", password_reset_done, name="password_reset_done"), SithPasswordChangeDoneView.as_view(),
url( name="password_change_done",
),
re_path(
r"^password_reset/$", SithPasswordResetView.as_view(), name="password_reset"
),
re_path(
r"^password_reset/done$",
SithPasswordResetDoneView.as_view(),
name="password_reset_done",
),
re_path(
r"^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$", r"^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$",
password_reset_confirm, SithPasswordResetConfirmView.as_view(),
name="password_reset_confirm", name="password_reset_confirm",
), ),
url(r"^reset/done/$", password_reset_complete, name="password_reset_complete"), re_path(
url(r"^register$", register, name="register"), r"^reset/done/$",
SithPasswordResetCompleteView.as_view(),
name="password_reset_complete",
),
re_path(r"^register$", register, name="register"),
# Group handling # Group handling
url(r"^group/$", GroupListView.as_view(), name="group_list"), re_path(r"^group/$", GroupListView.as_view(), name="group_list"),
url(r"^group/new$", GroupCreateView.as_view(), name="group_new"), re_path(r"^group/new$", GroupCreateView.as_view(), name="group_new"),
url(r"^group/(?P<group_id>[0-9]+)/$", GroupEditView.as_view(), name="group_edit"), re_path(
url( r"^group/(?P<group_id>[0-9]+)/$", GroupEditView.as_view(), name="group_edit"
),
re_path(
r"^group/(?P<group_id>[0-9]+)/delete$", r"^group/(?P<group_id>[0-9]+)/delete$",
GroupDeleteView.as_view(), GroupDeleteView.as_view(),
name="group_delete", name="group_delete",
), ),
url( re_path(
r"^group/(?P<group_id>[0-9]+)/detail$", r"^group/(?P<group_id>[0-9]+)/detail$",
GroupTemplateView.as_view(), GroupTemplateView.as_view(),
name="group_detail", name="group_detail",
), ),
# User views # User views
url(r"^user/$", UserListView.as_view(), name="user_list"), re_path(r"^user/$", UserListView.as_view(), name="user_list"),
url( re_path(
r"^user/(?P<user_id>[0-9]+)/mini$", r"^user/(?P<user_id>[0-9]+)/mini$",
UserMiniView.as_view(), UserMiniView.as_view(),
name="user_profile_mini", name="user_profile_mini",
), ),
url(r"^user/(?P<user_id>[0-9]+)/$", UserView.as_view(), name="user_profile"), re_path(r"^user/(?P<user_id>[0-9]+)/$", UserView.as_view(), name="user_profile"),
url( re_path(
r"^user/(?P<user_id>[0-9]+)/pictures$", r"^user/(?P<user_id>[0-9]+)/pictures$",
UserPicturesView.as_view(), UserPicturesView.as_view(),
name="user_pictures", name="user_pictures",
), ),
url( re_path(
r"^user/(?P<user_id>[0-9]+)/godfathers$", r"^user/(?P<user_id>[0-9]+)/godfathers$",
UserGodfathersView.as_view(), UserGodfathersView.as_view(),
name="user_godfathers", name="user_godfathers",
), ),
url( re_path(
r"^user/(?P<user_id>[0-9]+)/godfathers/tree$", r"^user/(?P<user_id>[0-9]+)/godfathers/tree$",
UserGodfathersTreeView.as_view(), UserGodfathersTreeView.as_view(),
name="user_godfathers_tree", name="user_godfathers_tree",
), ),
url( re_path(
r"^user/(?P<user_id>[0-9]+)/godfathers/tree/pict$", r"^user/(?P<user_id>[0-9]+)/godfathers/tree/pict$",
UserGodfathersTreePictureView.as_view(), UserGodfathersTreePictureView.as_view(),
name="user_godfathers_tree_pict", name="user_godfathers_tree_pict",
), ),
url( re_path(
r"^user/(?P<user_id>[0-9]+)/godfathers/(?P<godfather_id>[0-9]+)/(?P<is_father>(True)|(False))/delete$", r"^user/(?P<user_id>[0-9]+)/godfathers/(?P<godfather_id>[0-9]+)/(?P<is_father>(True)|(False))/delete$",
DeleteUserGodfathers, DeleteUserGodfathers,
name="user_godfathers_delete", name="user_godfathers_delete",
), ),
url( re_path(
r"^user/(?P<user_id>[0-9]+)/edit$", r"^user/(?P<user_id>[0-9]+)/edit$",
UserUpdateProfileView.as_view(), UserUpdateProfileView.as_view(),
name="user_edit", name="user_edit",
), ),
url( re_path(
r"^user/(?P<user_id>[0-9]+)/profile_upload$", r"^user/(?P<user_id>[0-9]+)/profile_upload$",
UserUploadProfilePictView.as_view(), UserUploadProfilePictView.as_view(),
name="user_profile_upload", name="user_profile_upload",
), ),
url(r"^user/(?P<user_id>[0-9]+)/clubs$", UserClubView.as_view(), name="user_clubs"), re_path(
url( r"^user/(?P<user_id>[0-9]+)/clubs$", UserClubView.as_view(), name="user_clubs"
),
re_path(
r"^user/(?P<user_id>[0-9]+)/prefs$", r"^user/(?P<user_id>[0-9]+)/prefs$",
UserPreferencesView.as_view(), UserPreferencesView.as_view(),
name="user_prefs", name="user_prefs",
), ),
url( re_path(
r"^user/(?P<user_id>[0-9]+)/groups$", r"^user/(?P<user_id>[0-9]+)/groups$",
UserUpdateGroupView.as_view(), UserUpdateGroupView.as_view(),
name="user_groups", name="user_groups",
), ),
url(r"^user/tools/$", UserToolsView.as_view(), name="user_tools"), re_path(r"^user/tools/$", UserToolsView.as_view(), name="user_tools"),
url( re_path(
r"^user/(?P<user_id>[0-9]+)/account$", r"^user/(?P<user_id>[0-9]+)/account$",
UserAccountView.as_view(), UserAccountView.as_view(),
name="user_account", name="user_account",
), ),
url( re_path(
r"^user/(?P<user_id>[0-9]+)/account/(?P<year>[0-9]+)/(?P<month>[0-9]+)$", r"^user/(?P<user_id>[0-9]+)/account/(?P<year>[0-9]+)/(?P<month>[0-9]+)$",
UserAccountDetailView.as_view(), UserAccountDetailView.as_view(),
name="user_account_detail", name="user_account_detail",
), ),
url( re_path(
r"^user/(?P<user_id>[0-9]+)/stats$", UserStatsView.as_view(), name="user_stats" r"^user/(?P<user_id>[0-9]+)/stats$", UserStatsView.as_view(), name="user_stats"
), ),
url( re_path(
r"^user/(?P<user_id>[0-9]+)/gift/create$", r"^user/(?P<user_id>[0-9]+)/gift/create$",
GiftCreateView.as_view(), GiftCreateView.as_view(),
name="user_gift_create", name="user_gift_create",
), ),
url( re_path(
r"^user/(?P<user_id>[0-9]+)/gift/delete/(?P<gift_id>[0-9]+)/$", r"^user/(?P<user_id>[0-9]+)/gift/delete/(?P<gift_id>[0-9]+)/$",
GiftDeleteView.as_view(), GiftDeleteView.as_view(),
name="user_gift_delete", name="user_gift_delete",
), ),
# File views # File views
# url(r'^file/add/(?P<popup>popup)?$', FileCreateView.as_view(), name='file_new'), # re_path(r'^file/add/(?P<popup>popup)?$', FileCreateView.as_view(), name='file_new'),
url(r"^file/(?P<popup>popup)?$", FileListView.as_view(), name="file_list"), re_path(r"^file/(?P<popup>popup)?$", FileListView.as_view(), name="file_list"),
url( re_path(
r"^file/(?P<file_id>[0-9]+)/(?P<popup>popup)?$", r"^file/(?P<file_id>[0-9]+)/(?P<popup>popup)?$",
FileView.as_view(), FileView.as_view(),
name="file_detail", name="file_detail",
), ),
url( re_path(
r"^file/(?P<file_id>[0-9]+)/edit/(?P<popup>popup)?$", r"^file/(?P<file_id>[0-9]+)/edit/(?P<popup>popup)?$",
FileEditView.as_view(), FileEditView.as_view(),
name="file_edit", name="file_edit",
), ),
url( re_path(
r"^file/(?P<file_id>[0-9]+)/prop/(?P<popup>popup)?$", r"^file/(?P<file_id>[0-9]+)/prop/(?P<popup>popup)?$",
FileEditPropView.as_view(), FileEditPropView.as_view(),
name="file_prop", name="file_prop",
), ),
url( re_path(
r"^file/(?P<file_id>[0-9]+)/delete/(?P<popup>popup)?$", r"^file/(?P<file_id>[0-9]+)/delete/(?P<popup>popup)?$",
FileDeleteView.as_view(), FileDeleteView.as_view(),
name="file_delete", name="file_delete",
), ),
url(r"^file/moderation$", FileModerationView.as_view(), name="file_moderation"), re_path(r"^file/moderation$", FileModerationView.as_view(), name="file_moderation"),
url( re_path(
r"^file/(?P<file_id>[0-9]+)/moderate$", r"^file/(?P<file_id>[0-9]+)/moderate$",
FileModerateView.as_view(), FileModerateView.as_view(),
name="file_moderate", name="file_moderate",
), ),
url(r"^file/(?P<file_id>[0-9]+)/download$", send_file, name="download"), re_path(r"^file/(?P<file_id>[0-9]+)/download$", send_file, name="download"),
# Page views # Page views
url(r"^page/$", PageListView.as_view(), name="page_list"), re_path(r"^page/$", PageListView.as_view(), name="page_list"),
url(r"^page/create$", PageCreateView.as_view(), name="page_new"), re_path(r"^page/create$", PageCreateView.as_view(), name="page_new"),
url( re_path(
r"^page/(?P<page_id>[0-9]*)/delete$", r"^page/(?P<page_id>[0-9]*)/delete$",
PageDeleteView.as_view(), PageDeleteView.as_view(),
name="page_delete", name="page_delete",
), ),
url( re_path(
r"^page/(?P<page_name>([/a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9])+)/edit$", r"^page/(?P<page_name>([/a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9])+)/edit$",
PageEditView.as_view(), PageEditView.as_view(),
name="page_edit", name="page_edit",
), ),
url( re_path(
r"^page/(?P<page_name>([/a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9])+)/prop$", r"^page/(?P<page_name>([/a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9])+)/prop$",
PagePropView.as_view(), PagePropView.as_view(),
name="page_prop", name="page_prop",
), ),
url( re_path(
r"^page/(?P<page_name>([/a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9])+)/hist$", r"^page/(?P<page_name>([/a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9])+)/hist$",
PageHistView.as_view(), PageHistView.as_view(),
name="page_hist", name="page_hist",
), ),
url( re_path(
r"^page/(?P<page_name>([/a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9])+)/rev/(?P<rev>[0-9]+)/", r"^page/(?P<page_name>([/a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9])+)/rev/(?P<rev>[0-9]+)/",
PageRevView.as_view(), PageRevView.as_view(),
name="page_rev", name="page_rev",
), ),
url( re_path(
r"^page/(?P<page_name>([/a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9])+)/$", r"^page/(?P<page_name>([/a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9])+)/$",
PageView.as_view(), PageView.as_view(),
name="page", name="page",

View File

@ -48,7 +48,7 @@ from core.models import Group
from core.views.forms import LoginForm from core.views.forms import LoginForm
def forbidden(request): def forbidden(request, exception):
try: try:
return HttpResponseForbidden( return HttpResponseForbidden(
render( render(
@ -71,7 +71,7 @@ def forbidden(request):
) )
def not_found(request): def not_found(request, exception):
return HttpResponseNotFound(render(request, "core/404.jinja")) return HttpResponseNotFound(render(request, "core/404.jinja"))
@ -150,7 +150,7 @@ class CanCreateMixin(View):
def dispatch(self, request, *arg, **kwargs): def dispatch(self, request, *arg, **kwargs):
res = super(CanCreateMixin, self).dispatch(request, *arg, **kwargs) res = super(CanCreateMixin, self).dispatch(request, *arg, **kwargs)
if not request.user.is_authenticated(): if not request.user.is_authenticated:
raise PermissionDenied raise PermissionDenied
return res return res

View File

@ -32,7 +32,7 @@ from django.conf import settings
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.http import HttpResponse from django.http import HttpResponse
from wsgiref.util import FileWrapper from wsgiref.util import FileWrapper
from django.core.urlresolvers import reverse from django.urls import reverse
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
from django import forms from django import forms
@ -109,7 +109,7 @@ class AddFilesForm(forms.Form):
owner=owner, owner=owner,
is_folder=False, is_folder=False,
mime_type=f.content_type, mime_type=f.content_type,
size=f._size, size=f.size,
) )
try: try:
new_file.clean() new_file.clean()
@ -289,7 +289,7 @@ class FileView(CanViewMixin, DetailView, FormMixin):
self.form = self.get_form() # The form handle only the file upload self.form = self.get_form() # The form handle only the file upload
files = request.FILES.getlist("file_field") files = request.FILES.getlist("file_field")
if ( if (
request.user.is_authenticated() request.user.is_authenticated
and request.user.can_edit(self.object) and request.user.can_edit(self.object)
and self.form.is_valid() and self.form.is_valid()
): ):

View File

@ -27,7 +27,7 @@ from django import forms
from django.conf import settings from django.conf import settings
from django.db import transaction from django.db import transaction
from django.templatetags.static import static from django.templatetags.static import static
from django.core.urlresolvers import reverse from django.urls import reverse
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.forms import ( from django.forms import (
CheckboxSelectMultiple, CheckboxSelectMultiple,
@ -56,39 +56,39 @@ from PIL import Image
class SelectSingle(Select): class SelectSingle(Select):
def render(self, name, value, attrs=None): def render(self, name, value, attrs=None, renderer=None):
if attrs: if attrs:
attrs["class"] = "select_single" attrs["class"] = "select_single"
else: else:
attrs = {"class": "select_single"} attrs = {"class": "select_single"}
return super(SelectSingle, self).render(name, value, attrs) return super(SelectSingle, self).render(name, value, attrs, renderer)
class SelectMultiple(Select): class SelectMultiple(Select):
def render(self, name, value, attrs=None): def render(self, name, value, attrs=None, renderer=None):
if attrs: if attrs:
attrs["class"] = "select_multiple" attrs["class"] = "select_multiple"
else: else:
attrs = {"class": "select_multiple"} attrs = {"class": "select_multiple"}
return super(SelectMultiple, self).render(name, value, attrs) return super(SelectMultiple, self).render(name, value, attrs, renderer)
class SelectDateTime(DateTimeInput): class SelectDateTime(DateTimeInput):
def render(self, name, value, attrs=None): def render(self, name, value, attrs=None, renderer=None):
if attrs: if attrs:
attrs["class"] = "select_datetime" attrs["class"] = "select_datetime"
else: else:
attrs = {"class": "select_datetime"} attrs = {"class": "select_datetime"}
return super(SelectDateTime, self).render(name, value, attrs) return super(SelectDateTime, self).render(name, value, attrs, renderer)
class SelectDate(DateInput): class SelectDate(DateInput):
def render(self, name, value, attrs=None): def render(self, name, value, attrs=None, renderer=None):
if attrs: if attrs:
attrs["class"] = "select_date" attrs["class"] = "select_date"
else: else:
attrs = {"class": "select_date"} attrs = {"class": "select_date"}
return super(SelectDate, self).render(name, value, attrs) return super(SelectDate, self).render(name, value, attrs, renderer)
class MarkdownInput(Textarea): class MarkdownInput(Textarea):
@ -127,7 +127,7 @@ class MarkdownInput(Textarea):
class SelectFile(TextInput): class SelectFile(TextInput):
def render(self, name, value, attrs=None): def render(self, name, value, attrs=None, renderer=None):
if attrs: if attrs:
attrs["class"] = "select_file" attrs["class"] = "select_file"
else: else:
@ -135,7 +135,7 @@ class SelectFile(TextInput):
output = ( output = (
'%(content)s<div name="%(name)s" class="choose_file_widget" title="%(title)s"></div>' '%(content)s<div name="%(name)s" class="choose_file_widget" title="%(title)s"></div>'
% { % {
"content": super(SelectFile, self).render(name, value, attrs), "content": super(SelectFile, self).render(name, value, attrs, renderer),
"title": _("Choose file"), "title": _("Choose file"),
"name": name, "name": name,
} }
@ -151,7 +151,7 @@ class SelectFile(TextInput):
class SelectUser(TextInput): class SelectUser(TextInput):
def render(self, name, value, attrs=None): def render(self, name, value, attrs=None, renderer=None):
if attrs: if attrs:
attrs["class"] = "select_user" attrs["class"] = "select_user"
else: else:
@ -159,7 +159,7 @@ class SelectUser(TextInput):
output = ( output = (
'%(content)s<div name="%(name)s" class="choose_user_widget" title="%(title)s"></div>' '%(content)s<div name="%(name)s" class="choose_user_widget" title="%(title)s"></div>'
% { % {
"content": super(SelectUser, self).render(name, value, attrs), "content": super(SelectUser, self).render(name, value, attrs, renderer),
"title": _("Choose user"), "title": _("Choose user"),
"name": name, "name": name,
} }
@ -302,7 +302,7 @@ class UserProfileForm(forms.ModelForm):
owner=self.instance, owner=self.instance,
is_folder=False, is_folder=False,
mime_type=f.content_type, mime_type=f.content_type,
size=f._size, size=f.size,
moderator=self.instance, moderator=self.instance,
is_moderated=True, is_moderated=True,
) )

View File

@ -29,7 +29,7 @@
from django.views.generic.edit import UpdateView, CreateView, DeleteView from django.views.generic.edit import UpdateView, CreateView, DeleteView
from django.views.generic import ListView from django.views.generic import ListView
from django.views.generic.edit import FormView from django.views.generic.edit import FormView
from django.core.urlresolvers import reverse_lazy from django.urls import reverse_lazy
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django import forms from django import forms

View File

@ -23,7 +23,7 @@
# #
# This file contains all the views that concern the page model # This file contains all the views that concern the page model
from django.core.urlresolvers import reverse_lazy from django.urls import reverse_lazy
from django.views.generic import ListView, DetailView from django.views.generic import ListView, DetailView
from django.views.generic.edit import UpdateView, CreateView, DeleteView from django.views.generic.edit import UpdateView, CreateView, DeleteView
from django.forms.models import modelform_factory from django.forms.models import modelform_factory

View File

@ -26,8 +26,9 @@
# This file contains all the views that concern the user model # This file contains all the views that concern the user model
from django.shortcuts import render, redirect, get_object_or_404 from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth import views from django.contrib.auth import views
from django.contrib.auth.forms import PasswordChangeForm
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.core.urlresolvers import reverse from django.urls import reverse
from django.core.exceptions import PermissionDenied, ValidationError from django.core.exceptions import PermissionDenied, ValidationError
from django.http import Http404, HttpResponse from django.http import Http404, HttpResponse
from django.views.generic.edit import UpdateView from django.views.generic.edit import UpdateView
@ -40,7 +41,7 @@ from django.views.generic import (
) )
from django.forms.models import modelform_factory from django.forms.models import modelform_factory
from django.forms import CheckboxSelectMultiple from django.forms import CheckboxSelectMultiple
from django.core.urlresolvers import reverse_lazy from django.urls import reverse_lazy
from django.template.response import TemplateResponse from django.template.response import TemplateResponse
from django.conf import settings from django.conf import settings
from django.views.generic.dates import YearMixin, MonthMixin from django.views.generic.dates import YearMixin, MonthMixin
@ -69,15 +70,31 @@ from counter.views import StudentCardForm
from trombi.views import UserTrombiForm from trombi.views import UserTrombiForm
def login(request): class SithLoginView(views.LoginView):
"""
The login View
""" """
The login view
Needs to be improve with correct handling of form exceptions template_name = "core/login.jinja"
authentication_form = LoginForm
form_class = PasswordChangeForm
class SithPasswordChangeView(views.PasswordChangeView):
""" """
return views.login( Allows a user to change its password
request, template_name="core/login.jinja", authentication_form=LoginForm """
)
template_name = "core/password_change.jinja"
success_url = reverse_lazy("core:password_change_done")
class SithPasswordChangeDoneView(views.PasswordChangeDoneView):
"""
Allows a user to change its password
"""
template_name = "core/password_change_done.jinja"
def logout(request): def logout(request):
@ -87,26 +104,6 @@ def logout(request):
return views.logout_then_login(request) return views.logout_then_login(request)
def password_change(request):
"""
Allows a user to change its password
"""
return views.password_change(
request,
template_name="core/password_change.jinja",
post_change_redirect=reverse("core:password_change_done"),
)
def password_change_done(request):
"""
Allows a user to change its password
"""
return views.password_change_done(
request, template_name="core/password_change_done.jinja"
)
def password_root_change(request, user_id): def password_root_change(request, user_id):
""" """
Allows a root user to change someone's password Allows a root user to change someone's password
@ -128,47 +125,39 @@ def password_root_change(request, user_id):
) )
def password_reset(request): class SithPasswordResetView(views.PasswordResetView):
""" """
Allows someone to enter an email adresse for resetting password Allows someone to enter an email adresse for resetting password
""" """
return views.password_reset(
request, template_name = "core/password_reset.jinja"
template_name="core/password_reset.jinja", email_template_name = "core/password_reset_email.jinja"
email_template_name="core/password_reset_email.jinja", success_url = reverse_lazy("core:password_reset_done")
post_reset_redirect="core:password_reset_done",
)
def password_reset_done(request): class SithPasswordResetDoneView(views.PasswordResetDoneView):
""" """
Confirm that the reset email has been sent Confirm that the reset email has been sent
""" """
return views.password_reset_done(
request, template_name="core/password_reset_done.jinja" template_name = "core/password_reset_done.jinja"
)
def password_reset_confirm(request, uidb64=None, token=None): class SithPasswordResetConfirmView(views.PasswordResetConfirmView):
""" """
Provide a reset password formular Provide a reset password form
""" """
return views.password_reset_confirm(
request, template_name = "core/password_reset_confirm.jinja"
uidb64=uidb64, success_url = reverse_lazy("core:password_reset_complete")
token=token,
post_reset_redirect="core:password_reset_complete",
template_name="core/password_reset_confirm.jinja",
)
def password_reset_complete(request): class SithPasswordResetCompleteView(views.PasswordResetCompleteView):
""" """
Confirm the password has sucessfully been reset Confirm the password has sucessfully been reset
""" """
return views.password_reset_complete(
request, template_name="core/password_reset_complete.jinja" template_name = "core/password_reset_complete.jinja"
)
def register(request): def register(request):
@ -641,7 +630,7 @@ class UserUploadProfilePictView(CanEditMixin, DetailView):
owner=self.object, owner=self.object,
is_folder=False, is_folder=False,
mime_type=f.content_type, mime_type=f.content_type,
size=f._size, size=f.size,
) )
new_file.file.name = name new_file.file.name = name
new_file.save() new_file.save()
@ -689,7 +678,7 @@ class UserUpdateProfileView(UserTabsMixin, CanEditMixin, UpdateView):
files = request.FILES.items() files = request.FILES.items()
self.form.process(files) self.form.process(files)
if ( if (
request.user.is_authenticated() request.user.is_authenticated
and request.user.can_edit(self.object) and request.user.can_edit(self.object)
and self.form.is_valid() and self.form.is_valid()
): ):

View File

@ -5,6 +5,7 @@ from django.db import migrations, models
import accounting.models import accounting.models
import django.db.models.deletion import django.db.models.deletion
from django.conf import settings from django.conf import settings
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -42,7 +43,14 @@ class Migration(migrations.Migration):
verbose_name="counter type", verbose_name="counter type",
), ),
), ),
("club", models.ForeignKey(to="club.Club", related_name="counters")), (
"club",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="club.Club",
related_name="counters",
),
),
( (
"edit_groups", "edit_groups",
models.ManyToManyField( models.ManyToManyField(
@ -58,7 +66,10 @@ class Migration(migrations.Migration):
( (
"user", "user",
models.OneToOneField( models.OneToOneField(
primary_key=True, serialize=False, to=settings.AUTH_USER_MODEL on_delete=django.db.models.deletion.CASCADE,
primary_key=True,
serialize=False,
to=settings.AUTH_USER_MODEL,
), ),
), ),
( (
@ -97,13 +108,17 @@ class Migration(migrations.Migration):
( (
"counter", "counter",
models.ForeignKey( models.ForeignKey(
to="counter.Counter", related_name="permanencies" on_delete=django.db.models.deletion.CASCADE,
to="counter.Counter",
related_name="permanencies",
), ),
), ),
( (
"user", "user",
models.ForeignKey( models.ForeignKey(
to=settings.AUTH_USER_MODEL, related_name="permanencies" on_delete=django.db.models.deletion.CASCADE,
to=settings.AUTH_USER_MODEL,
related_name="permanencies",
), ),
), ),
], ],
@ -169,7 +184,10 @@ class Migration(migrations.Migration):
( (
"club", "club",
models.ForeignKey( models.ForeignKey(
verbose_name="club", to="club.Club", related_name="products" on_delete=django.db.models.deletion.CASCADE,
verbose_name="club",
to="club.Club",
related_name="products",
), ),
), ),
( (
@ -268,15 +286,24 @@ class Migration(migrations.Migration):
), ),
( (
"counter", "counter",
models.ForeignKey(to="counter.Counter", related_name="refillings"), models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="counter.Counter",
related_name="refillings",
),
), ),
( (
"customer", "customer",
models.ForeignKey(to="counter.Customer", related_name="refillings"), models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="counter.Customer",
related_name="refillings",
),
), ),
( (
"operator", "operator",
models.ForeignKey( models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to=settings.AUTH_USER_MODEL, to=settings.AUTH_USER_MODEL,
related_name="refillings_as_operator", related_name="refillings_as_operator",
), ),

View File

@ -4,6 +4,7 @@ from __future__ import unicode_literals
from django.db import migrations, models from django.db import migrations, models
from django.conf import settings from django.conf import settings
import accounting.models import accounting.models
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -35,6 +36,7 @@ class Migration(migrations.Migration):
( (
"counter", "counter",
models.ForeignKey( models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="counter.Counter", to="counter.Counter",
related_name="cash_summaries", related_name="cash_summaries",
verbose_name="counter", verbose_name="counter",
@ -43,6 +45,7 @@ class Migration(migrations.Migration):
( (
"user", "user",
models.ForeignKey( models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to=settings.AUTH_USER_MODEL, to=settings.AUTH_USER_MODEL,
related_name="cash_summaries", related_name="cash_summaries",
verbose_name="user", verbose_name="user",
@ -74,6 +77,7 @@ class Migration(migrations.Migration):
( (
"cash_summary", "cash_summary",
models.ForeignKey( models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="counter.CashRegisterSummary", to="counter.CashRegisterSummary",
related_name="items", related_name="items",
verbose_name="cash summary", verbose_name="cash summary",
@ -86,6 +90,7 @@ class Migration(migrations.Migration):
model_name="permanency", model_name="permanency",
name="counter", name="counter",
field=models.ForeignKey( field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="counter.Counter", to="counter.Counter",
related_name="permanencies", related_name="permanencies",
verbose_name="counter", verbose_name="counter",
@ -95,6 +100,7 @@ class Migration(migrations.Migration):
model_name="permanency", model_name="permanency",
name="user", name="user",
field=models.ForeignKey( field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to=settings.AUTH_USER_MODEL, to=settings.AUTH_USER_MODEL,
related_name="permanencies", related_name="permanencies",
verbose_name="user", verbose_name="user",

View File

@ -2,6 +2,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import migrations, models from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -13,7 +14,10 @@ class Migration(migrations.Migration):
model_name="counter", model_name="counter",
name="club", name="club",
field=models.ForeignKey( field=models.ForeignKey(
verbose_name="club", to="club.Club", related_name="counters" on_delete=django.db.models.deletion.CASCADE,
verbose_name="club",
to="club.Club",
related_name="counters",
), ),
), ),
migrations.AlterField( migrations.AlterField(

View File

@ -2,6 +2,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import migrations, models from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -32,6 +33,7 @@ class Migration(migrations.Migration):
( (
"product", "product",
models.OneToOneField( models.OneToOneField(
on_delete=django.db.models.deletion.CASCADE,
verbose_name="product", verbose_name="product",
related_name="eticket", related_name="eticket",
to="counter.Product", to="counter.Product",

View File

@ -26,7 +26,7 @@ from django.db import models
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.utils import timezone from django.utils import timezone
from django.conf import settings from django.conf import settings
from django.core.urlresolvers import reverse from django.urls import reverse
from django.core.validators import MinLengthValidator from django.core.validators import MinLengthValidator
from django.forms import ValidationError from django.forms import ValidationError
from django.utils.functional import cached_property from django.utils.functional import cached_property
@ -51,7 +51,7 @@ class Customer(models.Model):
is used by other accounting classes as reference to the customer, rather than using User is used by other accounting classes as reference to the customer, rather than using User
""" """
user = models.OneToOneField(User, primary_key=True) user = models.OneToOneField(User, primary_key=True, on_delete=models.CASCADE)
account_id = models.CharField(_("account id"), max_length=10, unique=True) account_id = models.CharField(_("account id"), max_length=10, unique=True)
amount = CurrencyField(_("amount")) amount = CurrencyField(_("amount"))
recorded_products = models.IntegerField(_("recorded product"), default=0) recorded_products = models.IntegerField(_("recorded product"), default=0)
@ -163,7 +163,9 @@ class Product(models.Model):
icon = models.ImageField( icon = models.ImageField(
upload_to="products", null=True, blank=True, verbose_name=_("icon") upload_to="products", null=True, blank=True, verbose_name=_("icon")
) )
club = models.ForeignKey(Club, related_name="products", verbose_name=_("club")) club = models.ForeignKey(
Club, related_name="products", verbose_name=_("club"), on_delete=models.CASCADE
)
limit_age = models.IntegerField(_("limit age"), default=0) limit_age = models.IntegerField(_("limit age"), default=0)
tray = models.BooleanField(_("tray price"), default=False) tray = models.BooleanField(_("tray price"), default=False)
parent_product = models.ForeignKey( parent_product = models.ForeignKey(
@ -209,7 +211,9 @@ class Product(models.Model):
class Counter(models.Model): class Counter(models.Model):
name = models.CharField(_("name"), max_length=30) name = models.CharField(_("name"), max_length=30)
club = models.ForeignKey(Club, related_name="counters", verbose_name=_("club")) club = models.ForeignKey(
Club, related_name="counters", verbose_name=_("club"), on_delete=models.CASCADE
)
products = models.ManyToManyField( products = models.ManyToManyField(
Product, related_name="counters", verbose_name=_("products"), blank=True Product, related_name="counters", verbose_name=_("products"), blank=True
) )
@ -344,12 +348,19 @@ class Refilling(models.Model):
Handle the refilling Handle the refilling
""" """
counter = models.ForeignKey(Counter, related_name="refillings", blank=False) counter = models.ForeignKey(
Counter, related_name="refillings", blank=False, on_delete=models.CASCADE
)
amount = CurrencyField(_("amount")) amount = CurrencyField(_("amount"))
operator = models.ForeignKey( operator = models.ForeignKey(
User, related_name="refillings_as_operator", blank=False User,
related_name="refillings_as_operator",
blank=False,
on_delete=models.CASCADE,
)
customer = models.ForeignKey(
Customer, related_name="refillings", blank=False, on_delete=models.CASCADE
) )
customer = models.ForeignKey(Customer, related_name="refillings", blank=False)
date = models.DateTimeField(_("date")) date = models.DateTimeField(_("date"))
payment_method = models.CharField( payment_method = models.CharField(
_("payment method"), _("payment method"),
@ -584,9 +595,17 @@ class Permanency(models.Model):
This class aims at storing a traceability of who was barman where and when This class aims at storing a traceability of who was barman where and when
""" """
user = models.ForeignKey(User, related_name="permanencies", verbose_name=_("user")) user = models.ForeignKey(
User,
related_name="permanencies",
verbose_name=_("user"),
on_delete=models.CASCADE,
)
counter = models.ForeignKey( counter = models.ForeignKey(
Counter, related_name="permanencies", verbose_name=_("counter") Counter,
related_name="permanencies",
verbose_name=_("counter"),
on_delete=models.CASCADE,
) )
start = models.DateTimeField(_("start date")) start = models.DateTimeField(_("start date"))
end = models.DateTimeField(_("end date"), null=True, db_index=True) end = models.DateTimeField(_("end date"), null=True, db_index=True)
@ -607,10 +626,16 @@ class Permanency(models.Model):
class CashRegisterSummary(models.Model): class CashRegisterSummary(models.Model):
user = models.ForeignKey( user = models.ForeignKey(
User, related_name="cash_summaries", verbose_name=_("user") User,
related_name="cash_summaries",
verbose_name=_("user"),
on_delete=models.CASCADE,
) )
counter = models.ForeignKey( counter = models.ForeignKey(
Counter, related_name="cash_summaries", verbose_name=_("counter") Counter,
related_name="cash_summaries",
verbose_name=_("counter"),
on_delete=models.CASCADE,
) )
date = models.DateTimeField(_("date")) date = models.DateTimeField(_("date"))
comment = models.TextField(_("comment"), null=True, blank=True) comment = models.TextField(_("comment"), null=True, blank=True)
@ -683,7 +708,10 @@ class CashRegisterSummary(models.Model):
class CashRegisterSummaryItem(models.Model): class CashRegisterSummaryItem(models.Model):
cash_summary = models.ForeignKey( cash_summary = models.ForeignKey(
CashRegisterSummary, related_name="items", verbose_name=_("cash summary") CashRegisterSummary,
related_name="items",
verbose_name=_("cash summary"),
on_delete=models.CASCADE,
) )
value = CurrencyField(_("value")) value = CurrencyField(_("value"))
quantity = models.IntegerField(_("quantity"), default=0) quantity = models.IntegerField(_("quantity"), default=0)
@ -699,7 +727,10 @@ class Eticket(models.Model):
""" """
product = models.OneToOneField( product = models.OneToOneField(
Product, related_name="eticket", verbose_name=_("product") Product,
related_name="eticket",
verbose_name=_("product"),
on_delete=models.CASCADE,
) )
banner = models.ImageField( banner = models.ImageField(
upload_to="etickets", null=True, blank=True, verbose_name=_("banner") upload_to="etickets", null=True, blank=True, verbose_name=_("banner")
@ -772,4 +803,5 @@ class StudentCard(models.Model):
verbose_name=_("student cards"), verbose_name=_("student cards"),
null=False, null=False,
blank=False, blank=False,
on_delete=models.CASCADE,
) )

View File

@ -25,7 +25,7 @@
import re import re
from django.test import TestCase from django.test import TestCase
from django.core.urlresolvers import reverse from django.urls import reverse
from django.core.management import call_command from django.core.management import call_command
from core.models import User from core.models import User

View File

@ -22,119 +22,119 @@
# #
# #
from django.conf.urls import url from django.urls import re_path
from counter.views import * from counter.views import *
urlpatterns = [ urlpatterns = [
url(r"^(?P<counter_id>[0-9]+)$", CounterMain.as_view(), name="details"), re_path(r"^(?P<counter_id>[0-9]+)$", CounterMain.as_view(), name="details"),
url( re_path(
r"^(?P<counter_id>[0-9]+)/click/(?P<user_id>[0-9]+)$", r"^(?P<counter_id>[0-9]+)/click/(?P<user_id>[0-9]+)$",
CounterClick.as_view(), CounterClick.as_view(),
name="click", name="click",
), ),
url( re_path(
r"^(?P<counter_id>[0-9]+)/last_ops$", r"^(?P<counter_id>[0-9]+)/last_ops$",
CounterLastOperationsView.as_view(), CounterLastOperationsView.as_view(),
name="last_ops", name="last_ops",
), ),
url( re_path(
r"^(?P<counter_id>[0-9]+)/cash_summary$", r"^(?P<counter_id>[0-9]+)/cash_summary$",
CounterCashSummaryView.as_view(), CounterCashSummaryView.as_view(),
name="cash_summary", name="cash_summary",
), ),
url( re_path(
r"^(?P<counter_id>[0-9]+)/activity$", r"^(?P<counter_id>[0-9]+)/activity$",
CounterActivityView.as_view(), CounterActivityView.as_view(),
name="activity", name="activity",
), ),
url(r"^(?P<counter_id>[0-9]+)/stats$", CounterStatView.as_view(), name="stats"), re_path(r"^(?P<counter_id>[0-9]+)/stats$", CounterStatView.as_view(), name="stats"),
url(r"^(?P<counter_id>[0-9]+)/login$", CounterLogin.as_view(), name="login"), re_path(r"^(?P<counter_id>[0-9]+)/login$", CounterLogin.as_view(), name="login"),
url(r"^(?P<counter_id>[0-9]+)/logout$", CounterLogout.as_view(), name="logout"), re_path(r"^(?P<counter_id>[0-9]+)/logout$", CounterLogout.as_view(), name="logout"),
url( re_path(
r"^eticket/(?P<selling_id>[0-9]+)/pdf$", r"^eticket/(?P<selling_id>[0-9]+)/pdf$",
EticketPDFView.as_view(), EticketPDFView.as_view(),
name="eticket_pdf", name="eticket_pdf",
), ),
url( re_path(
r"^customer/(?P<customer_id>[0-9]+)/card/add$", r"^customer/(?P<customer_id>[0-9]+)/card/add$",
StudentCardFormView.as_view(), StudentCardFormView.as_view(),
name="add_student_card", name="add_student_card",
), ),
url( re_path(
r"^customer/(?P<customer_id>[0-9]+)/card/delete/(?P<card_id>[0-9]+)/$", r"^customer/(?P<customer_id>[0-9]+)/card/delete/(?P<card_id>[0-9]+)/$",
StudentCardDeleteView.as_view(), StudentCardDeleteView.as_view(),
name="delete_student_card", name="delete_student_card",
), ),
url(r"^admin/(?P<counter_id>[0-9]+)$", CounterEditView.as_view(), name="admin"), re_path(r"^admin/(?P<counter_id>[0-9]+)$", CounterEditView.as_view(), name="admin"),
url( re_path(
r"^admin/(?P<counter_id>[0-9]+)/prop$", r"^admin/(?P<counter_id>[0-9]+)/prop$",
CounterEditPropView.as_view(), CounterEditPropView.as_view(),
name="prop_admin", name="prop_admin",
), ),
url(r"^admin$", CounterListView.as_view(), name="admin_list"), re_path(r"^admin$", CounterListView.as_view(), name="admin_list"),
url(r"^admin/new$", CounterCreateView.as_view(), name="new"), re_path(r"^admin/new$", CounterCreateView.as_view(), name="new"),
url( re_path(
r"^admin/delete/(?P<counter_id>[0-9]+)$", r"^admin/delete/(?P<counter_id>[0-9]+)$",
CounterDeleteView.as_view(), CounterDeleteView.as_view(),
name="delete", name="delete",
), ),
url(r"^admin/invoices_call$", InvoiceCallView.as_view(), name="invoices_call"), re_path(r"^admin/invoices_call$", InvoiceCallView.as_view(), name="invoices_call"),
url( re_path(
r"^admin/cash_summary/list$", r"^admin/cash_summary/list$",
CashSummaryListView.as_view(), CashSummaryListView.as_view(),
name="cash_summary_list", name="cash_summary_list",
), ),
url( re_path(
r"^admin/cash_summary/(?P<cashsummary_id>[0-9]+)$", r"^admin/cash_summary/(?P<cashsummary_id>[0-9]+)$",
CashSummaryEditView.as_view(), CashSummaryEditView.as_view(),
name="cash_summary_edit", name="cash_summary_edit",
), ),
url(r"^admin/product/list$", ProductListView.as_view(), name="product_list"), re_path(r"^admin/product/list$", ProductListView.as_view(), name="product_list"),
url( re_path(
r"^admin/product/list_archived$", r"^admin/product/list_archived$",
ProductArchivedListView.as_view(), ProductArchivedListView.as_view(),
name="product_list_archived", name="product_list_archived",
), ),
url(r"^admin/product/create$", ProductCreateView.as_view(), name="new_product"), re_path(r"^admin/product/create$", ProductCreateView.as_view(), name="new_product"),
url( re_path(
r"^admin/product/(?P<product_id>[0-9]+)$", r"^admin/product/(?P<product_id>[0-9]+)$",
ProductEditView.as_view(), ProductEditView.as_view(),
name="product_edit", name="product_edit",
), ),
url( re_path(
r"^admin/producttype/list$", r"^admin/producttype/list$",
ProductTypeListView.as_view(), ProductTypeListView.as_view(),
name="producttype_list", name="producttype_list",
), ),
url( re_path(
r"^admin/producttype/create$", r"^admin/producttype/create$",
ProductTypeCreateView.as_view(), ProductTypeCreateView.as_view(),
name="new_producttype", name="new_producttype",
), ),
url( re_path(
r"^admin/producttype/(?P<type_id>[0-9]+)$", r"^admin/producttype/(?P<type_id>[0-9]+)$",
ProductTypeEditView.as_view(), ProductTypeEditView.as_view(),
name="producttype_edit", name="producttype_edit",
), ),
url(r"^admin/eticket/list$", EticketListView.as_view(), name="eticket_list"), re_path(r"^admin/eticket/list$", EticketListView.as_view(), name="eticket_list"),
url(r"^admin/eticket/new$", EticketCreateView.as_view(), name="new_eticket"), re_path(r"^admin/eticket/new$", EticketCreateView.as_view(), name="new_eticket"),
url( re_path(
r"^admin/eticket/(?P<eticket_id>[0-9]+)$", r"^admin/eticket/(?P<eticket_id>[0-9]+)$",
EticketEditView.as_view(), EticketEditView.as_view(),
name="edit_eticket", name="edit_eticket",
), ),
url( re_path(
r"^admin/selling/(?P<selling_id>[0-9]+)/delete$", r"^admin/selling/(?P<selling_id>[0-9]+)/delete$",
SellingDeleteView.as_view(), SellingDeleteView.as_view(),
name="selling_delete", name="selling_delete",
), ),
url( re_path(
r"^admin/refilling/(?P<refilling_id>[0-9]+)/delete$", r"^admin/refilling/(?P<refilling_id>[0-9]+)/delete$",
RefillingDeleteView.as_view(), RefillingDeleteView.as_view(),
name="refilling_delete", name="refilling_delete",
), ),
url( re_path(
r"^admin/(?P<counter_id>[0-9]+)/refillings$", r"^admin/(?P<counter_id>[0-9]+)/refillings$",
CounterRefillingListView.as_view(), CounterRefillingListView.as_view(),
name="refilling_list", name="refilling_list",

View File

@ -37,7 +37,7 @@ from django.views.generic.edit import (
) )
from django.forms.models import modelform_factory from django.forms.models import modelform_factory
from django.forms import CheckboxSelectMultiple from django.forms import CheckboxSelectMultiple
from django.core.urlresolvers import reverse_lazy, reverse from django.urls import reverse_lazy, reverse
from django.http import HttpResponseRedirect, HttpResponse from django.http import HttpResponseRedirect, HttpResponse
from django.utils import timezone from django.utils import timezone
from django import forms from django import forms
@ -323,7 +323,7 @@ class CounterMain(
) )
if self.object.type == "BAR": if self.object.type == "BAR":
kwargs["barmen"] = self.object.get_barmen_list() kwargs["barmen"] = self.object.get_barmen_list()
elif self.request.user.is_authenticated(): elif self.request.user.is_authenticated:
kwargs["barmen"] = [self.request.user] kwargs["barmen"] = [self.request.user]
if "last_basket" in self.request.session.keys(): if "last_basket" in self.request.session.keys():
kwargs["last_basket"] = self.request.session.pop("last_basket") kwargs["last_basket"] = self.request.session.pop("last_basket")
@ -372,7 +372,7 @@ class CounterClick(CounterTabsMixin, CanViewMixin, DetailView):
): ):
raise PermissionDenied raise PermissionDenied
else: else:
if not request.user.is_authenticated(): if not request.user.is_authenticated:
raise PermissionDenied raise PermissionDenied
return super(CounterClick, self).dispatch(request, *args, **kwargs) return super(CounterClick, self).dispatch(request, *args, **kwargs)
@ -387,7 +387,7 @@ class CounterClick(CounterTabsMixin, CanViewMixin, DetailView):
request.session["no_age"] = False request.session["no_age"] = False
self.refill_form = None self.refill_form = None
ret = super(CounterClick, self).get(request, *args, **kwargs) ret = super(CounterClick, self).get(request, *args, **kwargs)
if (self.object.type != "BAR" and not request.user.is_authenticated()) or ( if (self.object.type != "BAR" and not request.user.is_authenticated) or (
self.object.type == "BAR" and len(self.object.get_barmen_list()) < 1 self.object.type == "BAR" and len(self.object.get_barmen_list()) < 1
): # Check that at least one barman is logged in ): # Check that at least one barman is logged in
ret = self.cancel(request) # Otherwise, go to main view ret = self.cancel(request) # Otherwise, go to main view
@ -397,7 +397,7 @@ class CounterClick(CounterTabsMixin, CanViewMixin, DetailView):
""" Handle the many possibilities of the post request """ """ Handle the many possibilities of the post request """
self.object = self.get_object() self.object = self.get_object()
self.refill_form = None self.refill_form = None
if (self.object.type != "BAR" and not request.user.is_authenticated()) or ( if (self.object.type != "BAR" and not request.user.is_authenticated) or (
self.object.type == "BAR" and len(self.object.get_barmen_list()) < 1 self.object.type == "BAR" and len(self.object.get_barmen_list()) < 1
): # Check that at least one barman is logged in ): # Check that at least one barman is logged in
return self.cancel(request) return self.cancel(request)
@ -1554,13 +1554,13 @@ class CashSummaryEditView(CounterAdminTabsMixin, CounterAdminMixin, UpdateView):
class CashSummaryFormBase(forms.Form): class CashSummaryFormBase(forms.Form):
begin_date = forms.DateTimeField( begin_date = forms.DateTimeField(
["%Y-%m-%d %H:%M:%S"], input_formats=["%Y-%m-%d %H:%M:%S"],
label=_("Begin date"), label=_("Begin date"),
required=False, required=False,
widget=SelectDateTime, widget=SelectDateTime,
) )
end_date = forms.DateTimeField( end_date = forms.DateTimeField(
["%Y-%m-%d %H:%M:%S"], input_formats=["%Y-%m-%d %H:%M:%S"],
label=_("End date"), label=_("End date"),
required=False, required=False,
widget=SelectDateTime, widget=SelectDateTime,

View File

@ -4,6 +4,7 @@ from __future__ import unicode_literals
from django.db import migrations, models from django.db import migrations, models
import accounting.models import accounting.models
from django.conf import settings from django.conf import settings
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -27,6 +28,7 @@ class Migration(migrations.Migration):
( (
"user", "user",
models.ForeignKey( models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
verbose_name="user", verbose_name="user",
to=settings.AUTH_USER_MODEL, to=settings.AUTH_USER_MODEL,
related_name="baskets", related_name="baskets",
@ -62,7 +64,10 @@ class Migration(migrations.Migration):
( (
"basket", "basket",
models.ForeignKey( models.ForeignKey(
verbose_name="basket", to="eboutic.Basket", related_name="items" on_delete=django.db.models.deletion.CASCADE,
verbose_name="basket",
to="eboutic.Basket",
related_name="items",
), ),
), ),
], ],
@ -88,6 +93,7 @@ class Migration(migrations.Migration):
( (
"user", "user",
models.ForeignKey( models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
verbose_name="user", verbose_name="user",
to=settings.AUTH_USER_MODEL, to=settings.AUTH_USER_MODEL,
related_name="invoices", related_name="invoices",
@ -123,6 +129,7 @@ class Migration(migrations.Migration):
( (
"invoice", "invoice",
models.ForeignKey( models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
verbose_name="invoice", verbose_name="invoice",
to="eboutic.Invoice", to="eboutic.Invoice",
related_name="items", related_name="items",

View File

@ -37,7 +37,11 @@ class Basket(models.Model):
""" """
user = models.ForeignKey( user = models.ForeignKey(
User, related_name="baskets", verbose_name=_("user"), blank=False User,
related_name="baskets",
verbose_name=_("user"),
blank=False,
on_delete=models.CASCADE,
) )
date = models.DateTimeField(_("date"), auto_now=True) date = models.DateTimeField(_("date"), auto_now=True)
@ -80,7 +84,11 @@ class Invoice(models.Model):
""" """
user = models.ForeignKey( user = models.ForeignKey(
User, related_name="invoices", verbose_name=_("user"), blank=False User,
related_name="invoices",
verbose_name=_("user"),
blank=False,
on_delete=models.CASCADE,
) )
date = models.DateTimeField(_("date"), auto_now=True) date = models.DateTimeField(_("date"), auto_now=True)
validated = models.BooleanField(_("validated"), default=False) validated = models.BooleanField(_("validated"), default=False)
@ -158,10 +166,15 @@ class AbstractBaseItem(models.Model):
class BasketItem(AbstractBaseItem): class BasketItem(AbstractBaseItem):
basket = models.ForeignKey(Basket, related_name="items", verbose_name=_("basket")) basket = models.ForeignKey(
Basket, related_name="items", verbose_name=_("basket"), on_delete=models.CASCADE
)
class InvoiceItem(AbstractBaseItem): class InvoiceItem(AbstractBaseItem):
invoice = models.ForeignKey( invoice = models.ForeignKey(
Invoice, related_name="items", verbose_name=_("invoice") Invoice,
related_name="items",
verbose_name=_("invoice"),
on_delete=models.CASCADE,
) )

View File

@ -29,7 +29,7 @@ import urllib
from OpenSSL import crypto from OpenSSL import crypto
from django.test import TestCase from django.test import TestCase
from django.core.urlresolvers import reverse from django.urls import reverse
from django.core.management import call_command from django.core.management import call_command
from django.conf import settings from django.conf import settings

View File

@ -22,16 +22,16 @@
# #
# #
from django.conf.urls import url from django.urls import re_path
from eboutic.views import * from eboutic.views import *
urlpatterns = [ urlpatterns = [
# Subscription views # Subscription views
url(r"^$", EbouticMain.as_view(), name="main"), re_path(r"^$", EbouticMain.as_view(), name="main"),
url(r"^command$", EbouticCommand.as_view(), name="command"), re_path(r"^command$", EbouticCommand.as_view(), name="command"),
url(r"^pay$", EbouticPayWithSith.as_view(), name="pay_with_sith"), re_path(r"^pay$", EbouticPayWithSith.as_view(), name="pay_with_sith"),
url( re_path(
r"^et_autoanswer$", r"^et_autoanswer$",
EtransactionAutoAnswer.as_view(), EtransactionAutoAnswer.as_view(),
name="etransation_autoanswer", name="etransation_autoanswer",

View File

@ -28,7 +28,7 @@ import hmac
import base64 import base64
from OpenSSL import crypto from OpenSSL import crypto
from django.core.urlresolvers import reverse_lazy from django.urls import reverse_lazy
from django.views.generic import TemplateView, View from django.views.generic import TemplateView, View
from django.http import HttpResponse, HttpResponseRedirect from django.http import HttpResponse, HttpResponseRedirect
from django.core.exceptions import SuspiciousOperation from django.core.exceptions import SuspiciousOperation
@ -56,7 +56,7 @@ class EbouticMain(TemplateView):
request.session.modified = True request.session.modified = True
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
if not request.user.is_authenticated(): if not request.user.is_authenticated:
return HttpResponseRedirect( return HttpResponseRedirect(
reverse_lazy("core:login", args=self.args, kwargs=kwargs) reverse_lazy("core:login", args=self.args, kwargs=kwargs)
+ "?next=" + "?next="
@ -67,7 +67,7 @@ class EbouticMain(TemplateView):
return super(EbouticMain, self).get(request, *args, **kwargs) return super(EbouticMain, self).get(request, *args, **kwargs)
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
if not request.user.is_authenticated(): if not request.user.is_authenticated:
return HttpResponseRedirect( return HttpResponseRedirect(
reverse_lazy("core:login", args=self.args, kwargs=kwargs) reverse_lazy("core:login", args=self.args, kwargs=kwargs)
+ "?next=" + "?next="
@ -118,7 +118,7 @@ class EbouticCommand(TemplateView):
template_name = "eboutic/eboutic_makecommand.jinja" template_name = "eboutic/eboutic_makecommand.jinja"
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
if not request.user.is_authenticated(): if not request.user.is_authenticated:
return HttpResponseRedirect( return HttpResponseRedirect(
reverse_lazy("core:login", args=self.args, kwargs=kwargs) reverse_lazy("core:login", args=self.args, kwargs=kwargs)
+ "?next=" + "?next="
@ -129,7 +129,7 @@ class EbouticCommand(TemplateView):
) )
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
if not request.user.is_authenticated(): if not request.user.is_authenticated:
return HttpResponseRedirect( return HttpResponseRedirect(
reverse_lazy("core:login", args=self.args, kwargs=kwargs) reverse_lazy("core:login", args=self.args, kwargs=kwargs)
+ "?next=" + "?next="
@ -192,7 +192,7 @@ class EbouticPayWithSith(TemplateView):
with transaction.atomic(): with transaction.atomic():
if ( if (
"basket_id" not in request.session.keys() "basket_id" not in request.session.keys()
or not request.user.is_authenticated() or not request.user.is_authenticated
): ):
return HttpResponseRedirect( return HttpResponseRedirect(
reverse_lazy("eboutic:main", args=self.args, kwargs=kwargs) reverse_lazy("eboutic:main", args=self.args, kwargs=kwargs)

View File

@ -3,6 +3,7 @@ from __future__ import unicode_literals
from django.db import migrations, models from django.db import migrations, models
from django.conf import settings from django.conf import settings
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -120,6 +121,7 @@ class Migration(migrations.Migration):
( (
"election", "election",
models.ForeignKey( models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
verbose_name="election", verbose_name="election",
to="election.Election", to="election.Election",
related_name="election_lists", related_name="election_lists",
@ -151,6 +153,7 @@ class Migration(migrations.Migration):
( (
"election", "election",
models.ForeignKey( models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
verbose_name="election", verbose_name="election",
to="election.Election", to="election.Election",
related_name="roles", related_name="roles",
@ -181,7 +184,10 @@ class Migration(migrations.Migration):
( (
"role", "role",
models.ForeignKey( models.ForeignKey(
verbose_name="role", to="election.Role", related_name="votes" on_delete=django.db.models.deletion.CASCADE,
verbose_name="role",
to="election.Role",
related_name="votes",
), ),
), ),
], ],
@ -190,6 +196,7 @@ class Migration(migrations.Migration):
model_name="candidature", model_name="candidature",
name="election_list", name="election_list",
field=models.ForeignKey( field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
verbose_name="election list", verbose_name="election list",
to="election.ElectionList", to="election.ElectionList",
related_name="candidatures", related_name="candidatures",
@ -199,13 +206,17 @@ class Migration(migrations.Migration):
model_name="candidature", model_name="candidature",
name="role", name="role",
field=models.ForeignKey( field=models.ForeignKey(
verbose_name="role", to="election.Role", related_name="candidatures" on_delete=django.db.models.deletion.CASCADE,
verbose_name="role",
to="election.Role",
related_name="candidatures",
), ),
), ),
migrations.AddField( migrations.AddField(
model_name="candidature", model_name="candidature",
name="user", name="user",
field=models.ForeignKey( field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
verbose_name="user", verbose_name="user",
to=settings.AUTH_USER_MODEL, to=settings.AUTH_USER_MODEL,
related_name="candidates", related_name="candidates",

View File

@ -0,0 +1,18 @@
# Generated by Django 2.2.6 on 2019-10-05 22:49
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [("election", "0003_auto_20171202_1819")]
operations = [
migrations.AlterField(
model_name="role",
name="order",
field=models.PositiveIntegerField(
db_index=True, editable=False, verbose_name="order"
),
)
]

View File

@ -111,7 +111,10 @@ class Role(OrderedModel):
""" """
election = models.ForeignKey( election = models.ForeignKey(
Election, related_name="roles", verbose_name=_("election") Election,
related_name="roles",
verbose_name=_("election"),
on_delete=models.CASCADE,
) )
title = models.CharField(_("title"), max_length=255) title = models.CharField(_("title"), max_length=255)
description = models.TextField(_("description"), null=True, blank=True) description = models.TextField(_("description"), null=True, blank=True)
@ -155,7 +158,10 @@ class ElectionList(models.Model):
title = models.CharField(_("title"), max_length=255) title = models.CharField(_("title"), max_length=255)
election = models.ForeignKey( election = models.ForeignKey(
Election, related_name="election_lists", verbose_name=_("election") Election,
related_name="election_lists",
verbose_name=_("election"),
on_delete=models.CASCADE,
) )
def can_be_edited_by(self, user): def can_be_edited_by(self, user):
@ -175,13 +181,25 @@ class Candidature(models.Model):
This class is a component of responsability This class is a component of responsability
""" """
role = models.ForeignKey(Role, related_name="candidatures", verbose_name=_("role")) role = models.ForeignKey(
Role,
related_name="candidatures",
verbose_name=_("role"),
on_delete=models.CASCADE,
)
user = models.ForeignKey( user = models.ForeignKey(
User, verbose_name=_("user"), related_name="candidates", blank=True User,
verbose_name=_("user"),
related_name="candidates",
blank=True,
on_delete=models.CASCADE,
) )
program = models.TextField(_("description"), null=True, blank=True) program = models.TextField(_("description"), null=True, blank=True)
election_list = models.ForeignKey( election_list = models.ForeignKey(
ElectionList, related_name="candidatures", verbose_name=_("election list") ElectionList,
related_name="candidatures",
verbose_name=_("election list"),
on_delete=models.CASCADE,
) )
def delete(self): def delete(self):
@ -201,7 +219,9 @@ class Vote(models.Model):
This class allows to vote for candidates This class allows to vote for candidates
""" """
role = models.ForeignKey(Role, related_name="votes", verbose_name=_("role")) role = models.ForeignKey(
Role, related_name="votes", verbose_name=_("role"), on_delete=models.CASCADE
)
candidature = models.ManyToManyField( candidature = models.ManyToManyField(
Candidature, related_name="votes", verbose_name=_("candidature") Candidature, related_name="votes", verbose_name=_("candidature")
) )

View File

@ -1,5 +1,5 @@
from django.test import TestCase from django.test import TestCase
from django.core.urlresolvers import reverse from django.urls import reverse
from django.core.management import call_command from django.core.management import call_command
from django.conf import settings from django.conf import settings

View File

@ -1,55 +1,57 @@
from django.conf.urls import url from django.urls import re_path
from election.views import * from election.views import *
urlpatterns = [ urlpatterns = [
url(r"^$", ElectionsListView.as_view(), name="list"), re_path(r"^$", ElectionsListView.as_view(), name="list"),
url(r"^archived$", ElectionListArchivedView.as_view(), name="list_archived"), re_path(r"^archived$", ElectionListArchivedView.as_view(), name="list_archived"),
url(r"^add$", ElectionCreateView.as_view(), name="create"), re_path(r"^add$", ElectionCreateView.as_view(), name="create"),
url(r"^(?P<election_id>[0-9]+)/edit$", ElectionUpdateView.as_view(), name="update"), re_path(
url( r"^(?P<election_id>[0-9]+)/edit$", ElectionUpdateView.as_view(), name="update"
),
re_path(
r"^(?P<election_id>[0-9]+)/delete$", ElectionDeleteView.as_view(), name="delete" r"^(?P<election_id>[0-9]+)/delete$", ElectionDeleteView.as_view(), name="delete"
), ),
url( re_path(
r"^(?P<election_id>[0-9]+)/list/add$", r"^(?P<election_id>[0-9]+)/list/add$",
ElectionListCreateView.as_view(), ElectionListCreateView.as_view(),
name="create_list", name="create_list",
), ),
url( re_path(
r"^(?P<list_id>[0-9]+)/list/delete$", r"^(?P<list_id>[0-9]+)/list/delete$",
ElectionListDeleteView.as_view(), ElectionListDeleteView.as_view(),
name="delete_list", name="delete_list",
), ),
url( re_path(
r"^(?P<election_id>[0-9]+)/role/create$", r"^(?P<election_id>[0-9]+)/role/create$",
RoleCreateView.as_view(), RoleCreateView.as_view(),
name="create_role", name="create_role",
), ),
url( re_path(
r"^(?P<role_id>[0-9]+)/role/edit$", RoleUpdateView.as_view(), name="update_role" r"^(?P<role_id>[0-9]+)/role/edit$", RoleUpdateView.as_view(), name="update_role"
), ),
url( re_path(
r"^(?P<role_id>[0-9]+)/role/delete$", r"^(?P<role_id>[0-9]+)/role/delete$",
RoleDeleteView.as_view(), RoleDeleteView.as_view(),
name="delete_role", name="delete_role",
), ),
url( re_path(
r"^(?P<election_id>[0-9]+)/candidate/add$", r"^(?P<election_id>[0-9]+)/candidate/add$",
CandidatureCreateView.as_view(), CandidatureCreateView.as_view(),
name="candidate", name="candidate",
), ),
url( re_path(
r"^(?P<candidature_id>[0-9]+)/candidate/edit$", r"^(?P<candidature_id>[0-9]+)/candidate/edit$",
CandidatureUpdateView.as_view(), CandidatureUpdateView.as_view(),
name="update_candidate", name="update_candidate",
), ),
url( re_path(
r"^(?P<candidature_id>[0-9]+)/candidate/delete$", r"^(?P<candidature_id>[0-9]+)/candidate/delete$",
CandidatureDeleteView.as_view(), CandidatureDeleteView.as_view(),
name="delete_candidate", name="delete_candidate",
), ),
url(r"^(?P<election_id>[0-9]+)/vote$", VoteFormView.as_view(), name="vote"), re_path(r"^(?P<election_id>[0-9]+)/vote$", VoteFormView.as_view(), name="vote"),
url( re_path(
r"^(?P<election_id>[0-9]+)/detail$", ElectionDetailView.as_view(), name="detail" r"^(?P<election_id>[0-9]+)/detail$", ElectionDetailView.as_view(), name="detail"
), ),
] ]

View File

@ -2,7 +2,7 @@ from django.shortcuts import get_object_or_404
from django.views.generic import ListView, DetailView from django.views.generic import ListView, DetailView
from django.views.generic.edit import UpdateView, CreateView from django.views.generic.edit import UpdateView, CreateView
from django.views.generic.edit import DeleteView, FormView from django.views.generic.edit import DeleteView, FormView
from django.core.urlresolvers import reverse_lazy from django.urls import reverse_lazy
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
from django.db import transaction from django.db import transaction
@ -28,23 +28,10 @@ class LimitedCheckboxField(forms.ModelMultipleChoiceField):
automatic backend verification automatic backend verification
""" """
def __init__( def __init__(self, queryset, max_choice, **kwargs):
self,
queryset,
max_choice,
required=True,
widget=None,
label=None,
initial=None,
help_text="",
*args,
**kwargs
):
self.max_choice = max_choice self.max_choice = max_choice
widget = forms.CheckboxSelectMultiple() widget = forms.CheckboxSelectMultiple()
super(LimitedCheckboxField, self).__init__( super(LimitedCheckboxField, self).__init__(queryset, **kwargs)
queryset, None, required, widget, label, initial, help_text, *args, **kwargs
)
def clean(self, value): def clean(self, value):
qs = super(LimitedCheckboxField, self).clean(value) qs = super(LimitedCheckboxField, self).clean(value)
@ -181,22 +168,25 @@ class ElectionForm(forms.ModelForm):
) )
start_date = forms.DateTimeField( start_date = forms.DateTimeField(
["%Y-%m-%d %H:%M:%S"], input_formats=["%Y-%m-%d %H:%M:%S"],
label=_("Start date"), label=_("Start date"),
widget=SelectDateTime, widget=SelectDateTime,
required=True, required=True,
) )
end_date = forms.DateTimeField( end_date = forms.DateTimeField(
["%Y-%m-%d %H:%M:%S"], label=_("End date"), widget=SelectDateTime, required=True input_formats=["%Y-%m-%d %H:%M:%S"],
label=_("End date"),
widget=SelectDateTime,
required=True,
) )
start_candidature = forms.DateTimeField( start_candidature = forms.DateTimeField(
["%Y-%m-%d %H:%M:%S"], input_formats=["%Y-%m-%d %H:%M:%S"],
label=_("Start candidature"), label=_("Start candidature"),
widget=SelectDateTime, widget=SelectDateTime,
required=True, required=True,
) )
end_candidature = forms.DateTimeField( end_candidature = forms.DateTimeField(
["%Y-%m-%d %H:%M:%S"], input_formats=["%Y-%m-%d %H:%M:%S"],
label=_("End candidature"), label=_("End candidature"),
widget=SelectDateTime, widget=SelectDateTime,
required=True, required=True,
@ -550,7 +540,7 @@ class CandidatureUpdateView(CanEditMixin, UpdateView):
self.form = self.get_form() self.form = self.get_form()
self.remove_fields() self.remove_fields()
if ( if (
request.user.is_authenticated() request.user.is_authenticated
and request.user.can_edit(self.object) and request.user.can_edit(self.object)
and self.form.is_valid() and self.form.is_valid()
): ):
@ -594,7 +584,7 @@ class RoleUpdateView(CanEditMixin, UpdateView):
self.form = self.get_form() self.form = self.get_form()
self.remove_fields() self.remove_fields()
if ( if (
request.user.is_authenticated() request.user.is_authenticated
and request.user.can_edit(self.object) and request.user.can_edit(self.object)
and self.form.is_valid() and self.form.is_valid()
): ):

View File

@ -6,6 +6,7 @@ from django.utils.timezone import utc
from django.conf import settings from django.conf import settings
import django.utils.timezone import django.utils.timezone
import datetime import datetime
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -52,6 +53,7 @@ class Migration(migrations.Migration):
( (
"owner_club", "owner_club",
models.ForeignKey( models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="club.Club", to="club.Club",
verbose_name="owner club", verbose_name="owner club",
related_name="owned_forums", related_name="owned_forums",
@ -61,7 +63,11 @@ class Migration(migrations.Migration):
( (
"parent", "parent",
models.ForeignKey( models.ForeignKey(
to="forum.Forum", null=True, related_name="children", blank=True on_delete=django.db.models.deletion.CASCADE,
to="forum.Forum",
null=True,
related_name="children",
blank=True,
), ),
), ),
( (
@ -103,7 +109,9 @@ class Migration(migrations.Migration):
( (
"author", "author",
models.ForeignKey( models.ForeignKey(
related_name="forum_messages", to=settings.AUTH_USER_MODEL on_delete=django.db.models.deletion.CASCADE,
related_name="forum_messages",
to=settings.AUTH_USER_MODEL,
), ),
), ),
( (
@ -149,12 +157,18 @@ class Migration(migrations.Migration):
), ),
( (
"message", "message",
models.ForeignKey(related_name="metas", to="forum.ForumMessage"), models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="metas",
to="forum.ForumMessage",
),
), ),
( (
"user", "user",
models.ForeignKey( models.ForeignKey(
related_name="forum_message_metas", to=settings.AUTH_USER_MODEL on_delete=django.db.models.deletion.CASCADE,
related_name="forum_message_metas",
to=settings.AUTH_USER_MODEL,
), ),
), ),
], ],
@ -180,10 +194,19 @@ class Migration(migrations.Migration):
( (
"author", "author",
models.ForeignKey( models.ForeignKey(
related_name="forum_topics", to=settings.AUTH_USER_MODEL on_delete=django.db.models.deletion.CASCADE,
related_name="forum_topics",
to=settings.AUTH_USER_MODEL,
),
),
(
"forum",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="topics",
to="forum.Forum",
), ),
), ),
("forum", models.ForeignKey(related_name="topics", to="forum.Forum")),
], ],
options={"ordering": ["-id"]}, options={"ordering": ["-id"]},
), ),
@ -209,7 +232,9 @@ class Migration(migrations.Migration):
( (
"user", "user",
models.OneToOneField( models.OneToOneField(
to=settings.AUTH_USER_MODEL, related_name="_forum_infos" on_delete=django.db.models.deletion.CASCADE,
to=settings.AUTH_USER_MODEL,
related_name="_forum_infos",
), ),
), ),
], ],
@ -217,6 +242,10 @@ class Migration(migrations.Migration):
migrations.AddField( migrations.AddField(
model_name="forummessage", model_name="forummessage",
name="topic", name="topic",
field=models.ForeignKey(related_name="messages", to="forum.ForumTopic"), field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="messages",
to="forum.ForumTopic",
),
), ),
] ]

View File

@ -26,7 +26,7 @@ from django.db import models
from django.conf import settings from django.conf import settings
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.core.urlresolvers import reverse from django.urls import reverse
from django.utils import timezone from django.utils import timezone
from django.utils.functional import cached_property from django.utils.functional import cached_property
@ -58,12 +58,19 @@ class Forum(models.Model):
name = models.CharField(_("name"), max_length=64) name = models.CharField(_("name"), max_length=64)
description = models.CharField(_("description"), max_length=512, default="") description = models.CharField(_("description"), max_length=512, default="")
is_category = models.BooleanField(_("is a category"), default=False) is_category = models.BooleanField(_("is a category"), default=False)
parent = models.ForeignKey("Forum", related_name="children", null=True, blank=True) parent = models.ForeignKey(
"Forum",
related_name="children",
null=True,
blank=True,
on_delete=models.CASCADE,
)
owner_club = models.ForeignKey( owner_club = models.ForeignKey(
Club, Club,
related_name="owned_forums", related_name="owned_forums",
verbose_name=_("owner club"), verbose_name=_("owner club"),
default=settings.SITH_MAIN_CLUB_ID, default=settings.SITH_MAIN_CLUB_ID,
on_delete=models.CASCADE,
) )
edit_groups = models.ManyToManyField( edit_groups = models.ManyToManyField(
Group, Group,
@ -145,8 +152,8 @@ class Forum(models.Model):
"""Copy, if possible, the rights of the parent folder""" """Copy, if possible, the rights of the parent folder"""
if self.parent is not None: if self.parent is not None:
self.owner_club = self.parent.owner_club self.owner_club = self.parent.owner_club
self.edit_groups = self.parent.edit_groups.all() self.edit_groups.set(self.parent.edit_groups.all())
self.view_groups = self.parent.view_groups.all() self.view_groups.set(self.parent.view_groups.all())
self.save() self.save()
_club_memberships = {} # This cache is particularly efficient: _club_memberships = {} # This cache is particularly efficient:
@ -226,8 +233,10 @@ class Forum(models.Model):
class ForumTopic(models.Model): class ForumTopic(models.Model):
forum = models.ForeignKey(Forum, related_name="topics") forum = models.ForeignKey(Forum, related_name="topics", on_delete=models.CASCADE)
author = models.ForeignKey(User, related_name="forum_topics") author = models.ForeignKey(
User, related_name="forum_topics", on_delete=models.CASCADE
)
description = models.CharField(_("description"), max_length=256, default="") description = models.CharField(_("description"), max_length=256, default="")
subscribed_users = models.ManyToManyField( subscribed_users = models.ManyToManyField(
User, related_name="favorite_topics", verbose_name=_("subscribed users") User, related_name="favorite_topics", verbose_name=_("subscribed users")
@ -291,8 +300,12 @@ class ForumMessage(models.Model):
"A ForumMessage object represents a message in the forum" -- Cpt. Obvious "A ForumMessage object represents a message in the forum" -- Cpt. Obvious
""" """
topic = models.ForeignKey(ForumTopic, related_name="messages") topic = models.ForeignKey(
author = models.ForeignKey(User, related_name="forum_messages") ForumTopic, related_name="messages", on_delete=models.CASCADE
)
author = models.ForeignKey(
User, related_name="forum_messages", on_delete=models.CASCADE
)
title = models.CharField(_("title"), default="", max_length=64, blank=True) title = models.CharField(_("title"), default="", max_length=64, blank=True)
message = models.TextField(_("message"), default="") message = models.TextField(_("message"), default="")
date = models.DateTimeField(_("date"), default=timezone.now) date = models.DateTimeField(_("date"), default=timezone.now)
@ -386,8 +399,12 @@ MESSAGE_META_ACTIONS = [
class ForumMessageMeta(models.Model): class ForumMessageMeta(models.Model):
user = models.ForeignKey(User, related_name="forum_message_metas") user = models.ForeignKey(
message = models.ForeignKey(ForumMessage, related_name="metas") User, related_name="forum_message_metas", on_delete=models.CASCADE
)
message = models.ForeignKey(
ForumMessage, related_name="metas", on_delete=models.CASCADE
)
date = models.DateTimeField(_("date"), default=timezone.now) date = models.DateTimeField(_("date"), default=timezone.now)
action = models.CharField(_("action"), choices=MESSAGE_META_ACTIONS, max_length=16) action = models.CharField(_("action"), choices=MESSAGE_META_ACTIONS, max_length=16)
@ -404,7 +421,9 @@ class ForumUserInfo(models.Model):
user, such as the favourite topics, the signature, and so on... user, such as the favourite topics, the signature, and so on...
""" """
user = models.OneToOneField(User, related_name="_forum_infos") user = models.OneToOneField(
User, related_name="_forum_infos", on_delete=models.CASCADE
)
last_read_date = models.DateTimeField( last_read_date = models.DateTimeField(
_("last read date"), _("last read date"),
default=datetime( default=datetime(

View File

@ -22,64 +22,68 @@
# #
# #
from django.conf.urls import url from django.urls import re_path
from forum.views import * from forum.views import *
urlpatterns = [ urlpatterns = [
url(r"^$", ForumMainView.as_view(), name="main"), re_path(r"^$", ForumMainView.as_view(), name="main"),
url(r"^search/$", ForumSearchView.as_view(), name="search"), re_path(r"^search/$", ForumSearchView.as_view(), name="search"),
url(r"^new_forum$", ForumCreateView.as_view(), name="new_forum"), re_path(r"^new_forum$", ForumCreateView.as_view(), name="new_forum"),
url(r"^mark_all_as_read$", ForumMarkAllAsRead.as_view(), name="mark_all_as_read"), re_path(
url(r"^last_unread$", ForumLastUnread.as_view(), name="last_unread"), r"^mark_all_as_read$", ForumMarkAllAsRead.as_view(), name="mark_all_as_read"
url(r"^favorite_topics$", ForumFavoriteTopics.as_view(), name="favorite_topics"), ),
url(r"^(?P<forum_id>[0-9]+)$", ForumDetailView.as_view(), name="view_forum"), re_path(r"^last_unread$", ForumLastUnread.as_view(), name="last_unread"),
url(r"^(?P<forum_id>[0-9]+)/edit$", ForumEditView.as_view(), name="edit_forum"), re_path(
url( r"^favorite_topics$", ForumFavoriteTopics.as_view(), name="favorite_topics"
),
re_path(r"^(?P<forum_id>[0-9]+)$", ForumDetailView.as_view(), name="view_forum"),
re_path(r"^(?P<forum_id>[0-9]+)/edit$", ForumEditView.as_view(), name="edit_forum"),
re_path(
r"^(?P<forum_id>[0-9]+)/delete$", ForumDeleteView.as_view(), name="delete_forum" r"^(?P<forum_id>[0-9]+)/delete$", ForumDeleteView.as_view(), name="delete_forum"
), ),
url( re_path(
r"^(?P<forum_id>[0-9]+)/new_topic$", r"^(?P<forum_id>[0-9]+)/new_topic$",
ForumTopicCreateView.as_view(), ForumTopicCreateView.as_view(),
name="new_topic", name="new_topic",
), ),
url( re_path(
r"^topic/(?P<topic_id>[0-9]+)$", r"^topic/(?P<topic_id>[0-9]+)$",
ForumTopicDetailView.as_view(), ForumTopicDetailView.as_view(),
name="view_topic", name="view_topic",
), ),
url( re_path(
r"^topic/(?P<topic_id>[0-9]+)/edit$", r"^topic/(?P<topic_id>[0-9]+)/edit$",
ForumTopicEditView.as_view(), ForumTopicEditView.as_view(),
name="edit_topic", name="edit_topic",
), ),
url( re_path(
r"^topic/(?P<topic_id>[0-9]+)/new_message$", r"^topic/(?P<topic_id>[0-9]+)/new_message$",
ForumMessageCreateView.as_view(), ForumMessageCreateView.as_view(),
name="new_message", name="new_message",
), ),
url( re_path(
r"^topic/(?P<topic_id>[0-9]+)/toggle_subscribe$", r"^topic/(?P<topic_id>[0-9]+)/toggle_subscribe$",
ForumTopicSubscribeView.as_view(), ForumTopicSubscribeView.as_view(),
name="toggle_subscribe_topic", name="toggle_subscribe_topic",
), ),
url( re_path(
r"^message/(?P<message_id>[0-9]+)$", r"^message/(?P<message_id>[0-9]+)$",
ForumMessageView.as_view(), ForumMessageView.as_view(),
name="view_message", name="view_message",
), ),
url( re_path(
r"^message/(?P<message_id>[0-9]+)/edit$", r"^message/(?P<message_id>[0-9]+)/edit$",
ForumMessageEditView.as_view(), ForumMessageEditView.as_view(),
name="edit_message", name="edit_message",
), ),
url( re_path(
r"^message/(?P<message_id>[0-9]+)/delete$", r"^message/(?P<message_id>[0-9]+)/delete$",
ForumMessageDeleteView.as_view(), ForumMessageDeleteView.as_view(),
name="delete_message", name="delete_message",
), ),
url( re_path(
r"^message/(?P<message_id>[0-9]+)/undelete$", r"^message/(?P<message_id>[0-9]+)/undelete$",
ForumMessageUndeleteView.as_view(), ForumMessageUndeleteView.as_view(),
name="undelete_message", name="undelete_message",

View File

@ -28,7 +28,7 @@ from django.views.generic import ListView, DetailView, RedirectView
from django.views.generic.edit import UpdateView, CreateView, DeleteView from django.views.generic.edit import UpdateView, CreateView, DeleteView
from django.views.generic.detail import SingleObjectMixin from django.views.generic.detail import SingleObjectMixin
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.core.urlresolvers import reverse_lazy from django.urls import reverse_lazy
from django.utils import timezone, html from django.utils import timezone, html
from django.conf import settings from django.conf import settings
from django import forms from django import forms

View File

@ -2,6 +2,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import migrations, models from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -25,6 +26,7 @@ class Migration(migrations.Migration):
( (
"counter", "counter",
models.OneToOneField( models.OneToOneField(
on_delete=django.db.models.deletion.CASCADE,
related_name="launderette", related_name="launderette",
verbose_name="counter", verbose_name="counter",
to="counter.Counter", to="counter.Counter",
@ -61,6 +63,7 @@ class Migration(migrations.Migration):
( (
"launderette", "launderette",
models.ForeignKey( models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
verbose_name="launderette", verbose_name="launderette",
to="launderette.Launderette", to="launderette.Launderette",
related_name="machines", related_name="machines",
@ -93,6 +96,7 @@ class Migration(migrations.Migration):
( (
"machine", "machine",
models.ForeignKey( models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
verbose_name="machine", verbose_name="machine",
to="launderette.Machine", to="launderette.Machine",
related_name="slots", related_name="slots",
@ -131,6 +135,7 @@ class Migration(migrations.Migration):
( (
"launderette", "launderette",
models.ForeignKey( models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
verbose_name="launderette", verbose_name="launderette",
to="launderette.Launderette", to="launderette.Launderette",
related_name="tokens", related_name="tokens",
@ -139,6 +144,7 @@ class Migration(migrations.Migration):
( (
"user", "user",
models.ForeignKey( models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
null=True, null=True,
related_name="tokens", related_name="tokens",
verbose_name="user", verbose_name="user",
@ -153,6 +159,7 @@ class Migration(migrations.Migration):
model_name="slot", model_name="slot",
name="token", name="token",
field=models.ForeignKey( field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
null=True, null=True,
related_name="slots", related_name="slots",
verbose_name="token", verbose_name="token",
@ -164,7 +171,10 @@ class Migration(migrations.Migration):
model_name="slot", model_name="slot",
name="user", name="user",
field=models.ForeignKey( field=models.ForeignKey(
verbose_name="user", to="core.User", related_name="slots" on_delete=django.db.models.deletion.CASCADE,
verbose_name="user",
to="core.User",
related_name="slots",
), ),
), ),
migrations.AlterUniqueTogether( migrations.AlterUniqueTogether(

View File

@ -25,7 +25,7 @@
from django.db import models, DataError from django.db import models, DataError
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.conf import settings from django.conf import settings
from django.core.urlresolvers import reverse from django.urls import reverse
from counter.models import Counter from counter.models import Counter
from core.models import User from core.models import User
@ -37,7 +37,10 @@ from club.models import Club
class Launderette(models.Model): class Launderette(models.Model):
name = models.CharField(_("name"), max_length=30) name = models.CharField(_("name"), max_length=30)
counter = models.OneToOneField( counter = models.OneToOneField(
Counter, verbose_name=_("counter"), related_name="launderette" Counter,
verbose_name=_("counter"),
related_name="launderette",
on_delete=models.CASCADE,
) )
class Meta: class Meta:
@ -89,7 +92,10 @@ class Launderette(models.Model):
class Machine(models.Model): class Machine(models.Model):
name = models.CharField(_("name"), max_length=30) name = models.CharField(_("name"), max_length=30)
launderette = models.ForeignKey( launderette = models.ForeignKey(
Launderette, related_name="machines", verbose_name=_("launderette") Launderette,
related_name="machines",
verbose_name=_("launderette"),
on_delete=models.CASCADE,
) )
type = models.CharField( type = models.CharField(
_("type"), max_length=10, choices=settings.SITH_LAUNDERETTE_MACHINE_TYPES _("type"), max_length=10, choices=settings.SITH_LAUNDERETTE_MACHINE_TYPES
@ -124,14 +130,22 @@ class Machine(models.Model):
class Token(models.Model): class Token(models.Model):
name = models.CharField(_("name"), max_length=5) name = models.CharField(_("name"), max_length=5)
launderette = models.ForeignKey( launderette = models.ForeignKey(
Launderette, related_name="tokens", verbose_name=_("launderette") Launderette,
related_name="tokens",
verbose_name=_("launderette"),
on_delete=models.CASCADE,
) )
type = models.CharField( type = models.CharField(
_("type"), max_length=10, choices=settings.SITH_LAUNDERETTE_MACHINE_TYPES _("type"), max_length=10, choices=settings.SITH_LAUNDERETTE_MACHINE_TYPES
) )
borrow_date = models.DateTimeField(_("borrow date"), null=True, blank=True) borrow_date = models.DateTimeField(_("borrow date"), null=True, blank=True)
user = models.ForeignKey( user = models.ForeignKey(
User, related_name="tokens", verbose_name=_("user"), null=True, blank=True User,
related_name="tokens",
verbose_name=_("user"),
null=True,
blank=True,
on_delete=models.CASCADE,
) )
class Meta: class Meta:
@ -182,12 +196,22 @@ class Slot(models.Model):
_("type"), max_length=10, choices=settings.SITH_LAUNDERETTE_MACHINE_TYPES _("type"), max_length=10, choices=settings.SITH_LAUNDERETTE_MACHINE_TYPES
) )
machine = models.ForeignKey( machine = models.ForeignKey(
Machine, related_name="slots", verbose_name=_("machine") Machine,
related_name="slots",
verbose_name=_("machine"),
on_delete=models.CASCADE,
) )
token = models.ForeignKey( token = models.ForeignKey(
Token, related_name="slots", verbose_name=_("token"), blank=True, null=True Token,
related_name="slots",
verbose_name=_("token"),
blank=True,
null=True,
on_delete=models.CASCADE,
)
user = models.ForeignKey(
User, related_name="slots", verbose_name=_("user"), on_delete=models.CASCADE
) )
user = models.ForeignKey(User, related_name="slots", verbose_name=_("user"))
class Meta: class Meta:
verbose_name = _("Slot") verbose_name = _("Slot")

View File

@ -22,53 +22,53 @@
# #
# #
from django.conf.urls import url from django.urls import re_path
from launderette.views import * from launderette.views import *
urlpatterns = [ urlpatterns = [
# views # views
url(r"^$", LaunderetteMainView.as_view(), name="launderette_main"), re_path(r"^$", LaunderetteMainView.as_view(), name="launderette_main"),
url( re_path(
r"^slot/(?P<slot_id>[0-9]+)/delete$", r"^slot/(?P<slot_id>[0-9]+)/delete$",
SlotDeleteView.as_view(), SlotDeleteView.as_view(),
name="delete_slot", name="delete_slot",
), ),
url(r"^book$", LaunderetteBookMainView.as_view(), name="book_main"), re_path(r"^book$", LaunderetteBookMainView.as_view(), name="book_main"),
url( re_path(
r"^book/(?P<launderette_id>[0-9]+)$", r"^book/(?P<launderette_id>[0-9]+)$",
LaunderetteBookView.as_view(), LaunderetteBookView.as_view(),
name="book_slot", name="book_slot",
), ),
url( re_path(
r"^(?P<launderette_id>[0-9]+)/click$", r"^(?P<launderette_id>[0-9]+)/click$",
LaunderetteMainClickView.as_view(), LaunderetteMainClickView.as_view(),
name="main_click", name="main_click",
), ),
url( re_path(
r"^(?P<launderette_id>[0-9]+)/click/(?P<user_id>[0-9]+)$", r"^(?P<launderette_id>[0-9]+)/click/(?P<user_id>[0-9]+)$",
LaunderetteClickView.as_view(), LaunderetteClickView.as_view(),
name="click", name="click",
), ),
url(r"^admin$", LaunderetteListView.as_view(), name="launderette_list"), re_path(r"^admin$", LaunderetteListView.as_view(), name="launderette_list"),
url( re_path(
r"^admin/(?P<launderette_id>[0-9]+)$", r"^admin/(?P<launderette_id>[0-9]+)$",
LaunderetteAdminView.as_view(), LaunderetteAdminView.as_view(),
name="launderette_admin", name="launderette_admin",
), ),
url( re_path(
r"^admin/(?P<launderette_id>[0-9]+)/edit$", r"^admin/(?P<launderette_id>[0-9]+)/edit$",
LaunderetteEditView.as_view(), LaunderetteEditView.as_view(),
name="launderette_edit", name="launderette_edit",
), ),
url(r"^admin/new$", LaunderetteCreateView.as_view(), name="launderette_new"), re_path(r"^admin/new$", LaunderetteCreateView.as_view(), name="launderette_new"),
url(r"^admin/machine/new$", MachineCreateView.as_view(), name="machine_new"), re_path(r"^admin/machine/new$", MachineCreateView.as_view(), name="machine_new"),
url( re_path(
r"^admin/machine/(?P<machine_id>[0-9]+)/edit$", r"^admin/machine/(?P<machine_id>[0-9]+)/edit$",
MachineEditView.as_view(), MachineEditView.as_view(),
name="machine_edit", name="machine_edit",
), ),
url( re_path(
r"^admin/machine/(?P<machine_id>[0-9]+)/delete$", r"^admin/machine/(?P<machine_id>[0-9]+)/delete$",
MachineDeleteView.as_view(), MachineDeleteView.as_view(),
name="machine_delete", name="machine_delete",

View File

@ -30,7 +30,7 @@ from django.views.generic import ListView, DetailView, TemplateView
from django.views.generic.edit import UpdateView, CreateView, DeleteView, BaseFormView from django.views.generic.edit import UpdateView, CreateView, DeleteView, BaseFormView
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.utils import dateparse, timezone from django.utils import dateparse, timezone
from django.core.urlresolvers import reverse_lazy from django.urls import reverse_lazy
from django.conf import settings from django.conf import settings
from django.db import transaction, DataError from django.db import transaction, DataError
from django import forms from django import forms
@ -84,7 +84,7 @@ class LaunderetteBookView(CanViewMixin, DetailView):
self.object = self.get_object() self.object = self.get_object()
if "slot_type" in request.POST.keys(): if "slot_type" in request.POST.keys():
self.slot_type = request.POST["slot_type"] self.slot_type = request.POST["slot_type"]
if "slot" in request.POST.keys() and request.user.is_authenticated(): if "slot" in request.POST.keys() and request.user.is_authenticated:
self.subscriber = request.user self.subscriber = request.user
if self.subscriber.is_subscribed: if self.subscriber.is_subscribed:
self.date = dateparse.parse_datetime(request.POST["slot"]).replace( self.date = dateparse.parse_datetime(request.POST["slot"]).replace(

View File

@ -22,13 +22,13 @@
# #
# #
from django.conf.urls import url from django.urls import re_path
from matmat.views import * from matmat.views import *
urlpatterns = [ urlpatterns = [
url(r"^$", SearchNormalFormView.as_view(), name="search"), re_path(r"^$", SearchNormalFormView.as_view(), name="search"),
url(r"^reverse$", SearchReverseFormView.as_view(), name="search_reverse"), re_path(r"^reverse$", SearchReverseFormView.as_view(), name="search_reverse"),
url(r"^quick$", SearchQuickFormView.as_view(), name="search_quick"), re_path(r"^quick$", SearchQuickFormView.as_view(), name="search_quick"),
url(r"^clear$", SearchClearFormView.as_view(), name="search_clear"), re_path(r"^clear$", SearchClearFormView.as_view(), name="search_clear"),
] ]

View File

@ -29,7 +29,7 @@ from django.views.generic.edit import FormView
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.views.generic.detail import SingleObjectMixin from django.views.generic.detail import SingleObjectMixin
from django.http.response import HttpResponseRedirect from django.http.response import HttpResponseRedirect
from django.core.urlresolvers import reverse from django.urls import reverse
from django import forms from django import forms
from core.models import User from core.models import User
@ -70,7 +70,11 @@ class SearchForm(forms.ModelForm):
} }
sex = forms.ChoiceField( sex = forms.ChoiceField(
[("MAN", _("Man")), ("WOMAN", _("Woman")), ("INDIFFERENT", _("Indifferent"))], choices=[
("MAN", _("Man")),
("WOMAN", _("Woman")),
("INDIFFERENT", _("Indifferent")),
],
widget=forms.RadioSelect, widget=forms.RadioSelect,
initial="INDIFFERENT", initial="INDIFFERENT",
label=_("Sex"), label=_("Sex"),

View File

@ -28,7 +28,7 @@ from django.utils import timezone
from django.core import validators from django.core import validators
from django.conf import settings from django.conf import settings
from django.utils.functional import cached_property from django.utils.functional import cached_property
from django.core.urlresolvers import reverse from django.urls import reverse
from rest_framework import serializers from rest_framework import serializers
@ -61,6 +61,7 @@ class UV(models.Model):
verbose_name=_("author"), verbose_name=_("author"),
null=False, null=False,
blank=False, blank=False,
on_delete=models.CASCADE,
) )
credit_type = models.CharField( credit_type = models.CharField(
_("credit type"), _("credit type"),
@ -210,8 +211,11 @@ class UVComment(models.Model):
verbose_name=_("author"), verbose_name=_("author"),
null=False, null=False,
blank=False, blank=False,
on_delete=models.CASCADE,
)
uv = models.ForeignKey(
UV, related_name="comments", verbose_name=_("uv"), on_delete=models.CASCADE
) )
uv = models.ForeignKey(UV, related_name="comments", verbose_name=_("uv"))
comment = models.TextField(_("comment"), blank=True) comment = models.TextField(_("comment"), blank=True)
grade_global = models.IntegerField( grade_global = models.IntegerField(
_("global grade"), _("global grade"),
@ -283,8 +287,12 @@ class UVResult(models.Model):
a semester (P/A)20xx a semester (P/A)20xx
""" """
uv = models.ForeignKey(UV, related_name="results", verbose_name=_("uv")) uv = models.ForeignKey(
user = models.ForeignKey(User, related_name="uv_results", verbose_name=("user")) UV, related_name="results", verbose_name=_("uv"), on_delete=models.CASCADE
)
user = models.ForeignKey(
User, related_name="uv_results", verbose_name=("user"), on_delete=models.CASCADE
)
grade = models.CharField( grade = models.CharField(
_("grade"), _("grade"),
max_length=10, max_length=10,
@ -310,7 +318,10 @@ class UVCommentReport(models.Model):
on_delete=models.CASCADE, on_delete=models.CASCADE,
) )
reporter = models.ForeignKey( reporter = models.ForeignKey(
User, related_name="reported_uv_comment", verbose_name=_("reporter") User,
related_name="reported_uv_comment",
verbose_name=_("reporter"),
on_delete=models.CASCADE,
) )
reason = models.TextField(_("reason")) reason = models.TextField(_("reason"))

View File

@ -24,7 +24,7 @@
from django.conf import settings from django.conf import settings
from django.test import TestCase from django.test import TestCase
from django.core.urlresolvers import reverse from django.urls import reverse
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.core.management import call_command from django.core.management import call_command

View File

@ -22,33 +22,33 @@
# #
# #
from django.conf.urls import url from django.urls import re_path
from pedagogy.views import * from pedagogy.views import *
urlpatterns = [ urlpatterns = [
# Urls displaying the actual application for visitors # Urls displaying the actual application for visitors
url(r"^$", UVListView.as_view(), name="guide"), re_path(r"^$", UVListView.as_view(), name="guide"),
url(r"^uv/(?P<uv_id>[0-9]+)$", UVDetailFormView.as_view(), name="uv_detail"), re_path(r"^uv/(?P<uv_id>[0-9]+)$", UVDetailFormView.as_view(), name="uv_detail"),
url( re_path(
r"^comment/(?P<comment_id>[0-9]+)/edit$", r"^comment/(?P<comment_id>[0-9]+)/edit$",
UVCommentUpdateView.as_view(), UVCommentUpdateView.as_view(),
name="comment_update", name="comment_update",
), ),
url( re_path(
r"^comment/(?P<comment_id>[0-9]+)/delete$", r"^comment/(?P<comment_id>[0-9]+)/delete$",
UVCommentDeleteView.as_view(), UVCommentDeleteView.as_view(),
name="comment_delete", name="comment_delete",
), ),
url( re_path(
r"^comment/(?P<comment_id>[0-9]+)/report$", r"^comment/(?P<comment_id>[0-9]+)/report$",
UVCommentReportCreateView.as_view(), UVCommentReportCreateView.as_view(),
name="comment_report", name="comment_report",
), ),
# Moderation # Moderation
url(r"^moderation$", UVModerationFormView.as_view(), name="moderation"), re_path(r"^moderation$", UVModerationFormView.as_view(), name="moderation"),
# Administration : Create Update Delete Edit # Administration : Create Update Delete Edit
url(r"^uv/create$", UVCreateView.as_view(), name="uv_create"), re_path(r"^uv/create$", UVCreateView.as_view(), name="uv_create"),
url(r"^uv/(?P<uv_id>[0-9]+)/delete$", UVDeleteView.as_view(), name="uv_delete"), re_path(r"^uv/(?P<uv_id>[0-9]+)/delete$", UVDeleteView.as_view(), name="uv_delete"),
url(r"^uv/(?P<uv_id>[0-9]+)/edit$", UVUpdateView.as_view(), name="uv_update"), re_path(r"^uv/(?P<uv_id>[0-9]+)/edit$", UVUpdateView.as_view(), name="uv_update"),
] ]

View File

@ -33,7 +33,7 @@ from django.views.generic import (
from django.utils import html from django.utils import html
from django.http import HttpResponse from django.http import HttpResponse
from django.core.exceptions import PermissionDenied, ObjectDoesNotExist from django.core.exceptions import PermissionDenied, ObjectDoesNotExist
from django.core.urlresolvers import reverse_lazy, reverse from django.urls import reverse_lazy, reverse
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from django.conf import settings from django.conf import settings

View File

@ -1,11 +1,11 @@
# Django 1.11 LTS is required # Django 1.11 LTS is required
Django >=1.11, <2.0 Django >=2.2, <3.0
Pillow Pillow
mistune mistune
django-jinja django-jinja
pyopenssl pyopenssl
pytz pytz
djangorestframework <3.10 djangorestframework
django-phonenumber-field django-phonenumber-field
phonenumbers phonenumbers
django-ajax-selects django-ajax-selects

View File

@ -22,13 +22,13 @@
# #
# #
from django.conf.urls import url from django.urls import re_path
from rootplace.views import * from rootplace.views import *
urlpatterns = [ urlpatterns = [
url(r"^merge$", MergeUsersView.as_view(), name="merge"), re_path(r"^merge$", MergeUsersView.as_view(), name="merge"),
url( re_path(
r"^forum/messages/delete$", r"^forum/messages/delete$",
DeleteAllForumUserMessagesView.as_view(), DeleteAllForumUserMessagesView.as_view(),
name="delete_forum_messages", name="delete_forum_messages",

View File

@ -25,7 +25,7 @@
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.views.generic.edit import FormView from django.views.generic.edit import FormView
from django.core.urlresolvers import reverse from django.urls import reverse
from django import forms from django import forms
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied

View File

@ -3,6 +3,7 @@ from __future__ import unicode_literals
from django.db import migrations, models from django.db import migrations, models
from django.conf import settings from django.conf import settings
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -28,12 +29,16 @@ class Migration(migrations.Migration):
( (
"picture", "picture",
models.ForeignKey( models.ForeignKey(
related_name="people", to="sas.Picture", verbose_name="picture" on_delete=django.db.models.deletion.CASCADE,
related_name="people",
to="sas.Picture",
verbose_name="picture",
), ),
), ),
( (
"user", "user",
models.ForeignKey( models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="pictures", related_name="pictures",
to=settings.AUTH_USER_MODEL, to=settings.AUTH_USER_MODEL,
verbose_name="user", verbose_name="user",

View File

@ -23,7 +23,7 @@
# #
from django.db import models from django.db import models
from django.core.urlresolvers import reverse from django.urls import reverse
from django.core.cache import cache from django.core.cache import cache
from django.conf import settings from django.conf import settings
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
@ -240,7 +240,12 @@ class PeoplePictureRelation(models.Model):
""" """
user = models.ForeignKey( user = models.ForeignKey(
User, verbose_name=_("user"), related_name="pictures", null=False, blank=False User,
verbose_name=_("user"),
related_name="pictures",
null=False,
blank=False,
on_delete=models.CASCADE,
) )
picture = models.ForeignKey( picture = models.ForeignKey(
Picture, Picture,
@ -248,6 +253,7 @@ class PeoplePictureRelation(models.Model):
related_name="people", related_name="people",
null=False, null=False,
blank=False, blank=False,
on_delete=models.CASCADE,
) )
class Meta: class Meta:

View File

@ -22,40 +22,40 @@
# #
# #
from django.conf.urls import url from django.urls import re_path
from sas.views import * from sas.views import *
urlpatterns = [ urlpatterns = [
url(r"^$", SASMainView.as_view(), name="main"), re_path(r"^$", SASMainView.as_view(), name="main"),
url(r"^moderation$", ModerationView.as_view(), name="moderation"), re_path(r"^moderation$", ModerationView.as_view(), name="moderation"),
url(r"^album/(?P<album_id>[0-9]+)$", AlbumView.as_view(), name="album"), re_path(r"^album/(?P<album_id>[0-9]+)$", AlbumView.as_view(), name="album"),
url( re_path(
r"^album/(?P<album_id>[0-9]+)/upload$", r"^album/(?P<album_id>[0-9]+)/upload$",
AlbumUploadView.as_view(), AlbumUploadView.as_view(),
name="album_upload", name="album_upload",
), ),
url( re_path(
r"^album/(?P<album_id>[0-9]+)/edit$", AlbumEditView.as_view(), name="album_edit" r"^album/(?P<album_id>[0-9]+)/edit$", AlbumEditView.as_view(), name="album_edit"
), ),
url(r"^album/(?P<album_id>[0-9]+)/preview$", send_album, name="album_preview"), re_path(r"^album/(?P<album_id>[0-9]+)/preview$", send_album, name="album_preview"),
url(r"^picture/(?P<picture_id>[0-9]+)$", PictureView.as_view(), name="picture"), re_path(r"^picture/(?P<picture_id>[0-9]+)$", PictureView.as_view(), name="picture"),
url( re_path(
r"^picture/(?P<picture_id>[0-9]+)/edit$", r"^picture/(?P<picture_id>[0-9]+)/edit$",
PictureEditView.as_view(), PictureEditView.as_view(),
name="picture_edit", name="picture_edit",
), ),
url(r"^picture/(?P<picture_id>[0-9]+)/download$", send_pict, name="download"), re_path(r"^picture/(?P<picture_id>[0-9]+)/download$", send_pict, name="download"),
url( re_path(
r"^picture/(?P<picture_id>[0-9]+)/download/compressed$", r"^picture/(?P<picture_id>[0-9]+)/download/compressed$",
send_compressed, send_compressed,
name="download_compressed", name="download_compressed",
), ),
url( re_path(
r"^picture/(?P<picture_id>[0-9]+)/download/thumb$", r"^picture/(?P<picture_id>[0-9]+)/download/thumb$",
send_thumb, send_thumb,
name="download_thumb", name="download_thumb",
), ),
# url(r'^album/new$', AlbumCreateView.as_view(), name='album_new'), # re_path(r'^album/new$', AlbumCreateView.as_view(), name='album_new'),
# url(r'^(?P<club_id>[0-9]+)/$', ClubView.as_view(), name='club_view'), # re_path(r'^(?P<club_id>[0-9]+)/$', ClubView.as_view(), name='club_view'),
] ]

View File

@ -24,7 +24,7 @@
from django.shortcuts import redirect from django.shortcuts import redirect
from django.http import HttpResponse, Http404 from django.http import HttpResponse, Http404
from django.core.urlresolvers import reverse_lazy, reverse from django.urls import reverse_lazy, reverse
from core.views.forms import SelectDate from core.views.forms import SelectDate
from django.views.generic import DetailView, TemplateView from django.views.generic import DetailView, TemplateView
from django.views.generic.edit import UpdateView, FormMixin, FormView from django.views.generic.edit import UpdateView, FormMixin, FormView
@ -78,7 +78,7 @@ class SASForm(forms.Form):
file=f, file=f,
owner=owner, owner=owner,
mime_type=f.content_type, mime_type=f.content_type,
size=f._size, size=f.size,
is_folder=False, is_folder=False,
is_moderated=automodere, is_moderated=automodere,
) )
@ -117,7 +117,7 @@ class SASMainView(FormView):
parent = SithFile.objects.filter(id=settings.SITH_SAS_ROOT_DIR_ID).first() parent = SithFile.objects.filter(id=settings.SITH_SAS_ROOT_DIR_ID).first()
files = request.FILES.getlist("images") files = request.FILES.getlist("images")
root = User.objects.filter(username="root").first() root = User.objects.filter(username="root").first()
if request.user.is_authenticated() and request.user.is_in_group( if request.user.is_authenticated and request.user.is_in_group(
settings.SITH_GROUP_SAS_ADMIN_ID settings.SITH_GROUP_SAS_ADMIN_ID
): ):
if self.form.is_valid(): if self.form.is_valid():
@ -176,7 +176,7 @@ class PictureView(CanViewMixin, DetailView, FormMixin):
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
self.object = self.get_object() self.object = self.get_object()
self.form = self.get_form() self.form = self.get_form()
if request.user.is_authenticated() and request.user.was_subscribed: if request.user.is_authenticated and request.user.was_subscribed:
if self.form.is_valid(): if self.form.is_valid():
for uid in self.form.cleaned_data["users"]: for uid in self.form.cleaned_data["users"]:
u = User.objects.filter(id=uid).first() u = User.objects.filter(id=uid).first()
@ -233,7 +233,7 @@ class AlbumUploadView(CanViewMixin, DetailView, FormMixin):
self.form = self.get_form() self.form = self.get_form()
parent = SithFile.objects.filter(id=self.object.id).first() parent = SithFile.objects.filter(id=self.object.id).first()
files = request.FILES.getlist("images") files = request.FILES.getlist("images")
if request.user.is_authenticated() and request.user.is_subscribed: if request.user.is_authenticated and request.user.is_subscribed:
if self.form.is_valid(): if self.form.is_valid():
self.form.process( self.form.process(
parent=parent, parent=parent,
@ -279,7 +279,7 @@ class AlbumView(CanViewMixin, DetailView, FormMixin):
FileView.handle_clipboard(request, self.object) FileView.handle_clipboard(request, self.object)
parent = SithFile.objects.filter(id=self.object.id).first() parent = SithFile.objects.filter(id=self.object.id).first()
files = request.FILES.getlist("images") files = request.FILES.getlist("images")
if request.user.is_authenticated() and request.user.is_subscribed: if request.user.is_authenticated and request.user.is_subscribed:
if self.form.is_valid(): if self.form.is_valid():
self.form.process( self.form.process(
parent=parent, parent=parent,

View File

@ -101,7 +101,6 @@ MIDDLEWARE = (
"django.middleware.common.CommonMiddleware", "django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware", "django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware", "django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.auth.middleware.SessionAuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware", "django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.locale.LocaleMiddleware", "django.middleware.locale.LocaleMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware",

View File

@ -37,11 +37,11 @@ Including another URLconf
1. Add an import: from blog import urls as blog_urls 1. Add an import: from blog import urls as blog_urls
2. Add a URL to urlpatterns: url(r'^blog/', include(blog_urls)) 2. Add a URL to urlpatterns: url(r'^blog/', include(blog_urls))
""" """
from django.conf.urls import include, url from django.urls import include, re_path
from django.contrib import admin from django.contrib import admin
from django.conf.urls.static import static
from django.conf import settings from django.conf import settings
from django.views.i18n import javascript_catalog from django.conf.urls.static import static
from django.views.i18n import JavaScriptCatalog
from ajax_select import urls as ajax_select_urls from ajax_select import urls as ajax_select_urls
js_info_dict = {"packages": ("sith",)} js_info_dict = {"packages": ("sith",)}
@ -51,48 +51,43 @@ handler404 = "core.views.not_found"
handler500 = "core.views.internal_servor_error" handler500 = "core.views.internal_servor_error"
urlpatterns = [ urlpatterns = [
url(r"^", include("core.urls", namespace="core", app_name="core")), re_path(r"^", include(("core.urls", "core"), namespace="core")),
url( re_path(
r"^rootplace/", r"^rootplace/", include(("rootplace.urls", "rootplace"), namespace="rootplace")
include("rootplace.urls", namespace="rootplace", app_name="rootplace"),
), ),
url( re_path(
r"^subscription/", r"^subscription/",
include("subscription.urls", namespace="subscription", app_name="subscription"), include(("subscription.urls", "subscription"), namespace="subscription"),
), ),
url(r"^com/", include("com.urls", namespace="com", app_name="com")), re_path(r"^com/", include(("com.urls", "com"), namespace="com")),
url(r"^club/", include("club.urls", namespace="club", app_name="club")), re_path(r"^club/", include(("club.urls", "club"), namespace="club")),
url(r"^counter/", include("counter.urls", namespace="counter", app_name="counter")), re_path(r"^counter/", include(("counter.urls", "counter"), namespace="counter")),
url(r"^stock/", include("stock.urls", namespace="stock", app_name="stock")), re_path(r"^stock/", include(("stock.urls", "stock"), namespace="stock")),
url( re_path(
r"^accounting/", r"^accounting/",
include("accounting.urls", namespace="accounting", app_name="accounting"), include(("accounting.urls", "accounting"), namespace="accounting"),
), ),
url(r"^eboutic/", include("eboutic.urls", namespace="eboutic", app_name="eboutic")), re_path(r"^eboutic/", include(("eboutic.urls", "eboutic"), namespace="eboutic")),
url( re_path(
r"^launderette/", r"^launderette/",
include("launderette.urls", namespace="launderette", app_name="launderette"), include(("launderette.urls", "launderette"), namespace="launderette"),
), ),
url(r"^sas/", include("sas.urls", namespace="sas", app_name="sas")), re_path(r"^sas/", include(("sas.urls", "sas"), namespace="sas")),
url(r"^api/v1/", include("api.urls", namespace="api", app_name="api")), re_path(r"^api/v1/", include(("api.urls", "api"), namespace="api")),
url( re_path(
r"^election/", r"^election/", include(("election.urls", "election"), namespace="election")
include("election.urls", namespace="election", app_name="election"),
), ),
url(r"^forum/", include("forum.urls", namespace="forum", app_name="forum")), re_path(r"^forum/", include(("forum.urls", "forum"), namespace="forum")),
url(r"^trombi/", include("trombi.urls", namespace="trombi", app_name="trombi")), re_path(r"^trombi/", include(("trombi.urls", "trombi"), namespace="trombi")),
url( re_path(r"^matmatronch/", include(("matmat.urls", "matmat"), namespace="matmat")),
r"^matmatronch/", include("matmat.urls", namespace="matmat", app_name="matmat") re_path(
r"^pedagogy/", include(("pedagogy.urls", "pedagogy"), namespace="pedagogy")
), ),
url( re_path(r"^admin/", admin.site.urls),
r"^pedagogy/", re_path(r"^ajax_select/", include(ajax_select_urls)),
include("pedagogy.urls", namespace="pedagogy", app_name="pedagogy"), re_path(r"^i18n/", include("django.conf.urls.i18n")),
), re_path(r"^jsi18n/$", JavaScriptCatalog.as_view(), name="javascript-catalog"),
url(r"^admin/", include(admin.site.urls)), re_path(r"^captcha/", include("captcha.urls")),
url(r"^ajax_select/", include(ajax_select_urls)),
url(r"^i18n/", include("django.conf.urls.i18n")),
url(r"^jsi18n/$", javascript_catalog, js_info_dict, name="javascript-catalog"),
url(r"^captcha/", include("captcha.urls")),
] ]
if settings.DEBUG: if settings.DEBUG:
@ -100,4 +95,4 @@ if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
import debug_toolbar import debug_toolbar
urlpatterns += [url(r"^__debug__/", include(debug_toolbar.urls))] urlpatterns += [re_path(r"^__debug__/", include(debug_toolbar.urls))]

View File

@ -86,6 +86,7 @@ class Migration(migrations.Migration):
( (
"counter", "counter",
models.OneToOneField( models.OneToOneField(
on_delete=django.db.models.deletion.CASCADE,
verbose_name="counter", verbose_name="counter",
related_name="stock", related_name="stock",
to="counter.Counter", to="counter.Counter",
@ -132,7 +133,11 @@ class Migration(migrations.Migration):
), ),
( (
"stock_owner", "stock_owner",
models.ForeignKey(related_name="items", to="stock.Stock"), models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="items",
to="stock.Stock",
),
), ),
( (
"type", "type",
@ -151,7 +156,10 @@ class Migration(migrations.Migration):
model_name="shoppinglistitem", model_name="shoppinglistitem",
name="stockitem_owner", name="stockitem_owner",
field=models.ForeignKey( field=models.ForeignKey(
null=True, related_name="shopping_item", to="stock.StockItem" on_delete=django.db.models.deletion.CASCADE,
null=True,
related_name="shopping_item",
to="stock.StockItem",
), ),
), ),
migrations.AddField( migrations.AddField(
@ -170,7 +178,10 @@ class Migration(migrations.Migration):
model_name="shoppinglist", model_name="shoppinglist",
name="stock_owner", name="stock_owner",
field=models.ForeignKey( field=models.ForeignKey(
null=True, related_name="shopping_lists", to="stock.Stock" on_delete=django.db.models.deletion.CASCADE,
null=True,
related_name="shopping_lists",
to="stock.Stock",
), ),
), ),
] ]

View File

@ -25,7 +25,7 @@
from django.db import models from django.db import models
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.core.urlresolvers import reverse from django.urls import reverse
from django.conf import settings from django.conf import settings
@ -39,7 +39,10 @@ class Stock(models.Model):
name = models.CharField(_("name"), max_length=64) name = models.CharField(_("name"), max_length=64)
counter = models.OneToOneField( counter = models.OneToOneField(
Counter, verbose_name=_("counter"), related_name="stock" Counter,
verbose_name=_("counter"),
related_name="stock",
on_delete=models.CASCADE,
) )
def __str__(self): def __str__(self):
@ -79,7 +82,9 @@ class StockItem(models.Model):
blank=True, blank=True,
on_delete=models.SET_NULL, on_delete=models.SET_NULL,
) )
stock_owner = models.ForeignKey(Stock, related_name="items") stock_owner = models.ForeignKey(
Stock, related_name="items", on_delete=models.CASCADE
)
def __str__(self): def __str__(self):
return "%s" % (self.name) return "%s" % (self.name)
@ -100,7 +105,9 @@ class ShoppingList(models.Model):
name = models.CharField(_("name"), max_length=64) name = models.CharField(_("name"), max_length=64)
todo = models.BooleanField(_("todo")) todo = models.BooleanField(_("todo"))
comment = models.TextField(_("comment"), null=True, blank=True) comment = models.TextField(_("comment"), null=True, blank=True)
stock_owner = models.ForeignKey(Stock, null=True, related_name="shopping_lists") stock_owner = models.ForeignKey(
Stock, null=True, related_name="shopping_lists", on_delete=models.CASCADE
)
def __str__(self): def __str__(self):
return "%s (%s)" % (self.name, self.date) return "%s (%s)" % (self.name, self.date)
@ -122,7 +129,7 @@ class ShoppingListItem(models.Model):
related_name="shopping_items_to_buy", related_name="shopping_items_to_buy",
) )
stockitem_owner = models.ForeignKey( stockitem_owner = models.ForeignKey(
StockItem, related_name="shopping_item", null=True StockItem, related_name="shopping_item", null=True, on_delete=models.CASCADE
) )
name = models.CharField(_("name"), max_length=64) name = models.CharField(_("name"), max_length=64)
type = models.ForeignKey( type = models.ForeignKey(

Some files were not shown because too many files have changed in this diff Show More