mirror of
https://github.com/ae-utbm/sith.git
synced 2024-10-31 19:38:04 +00:00
Merge branch 'new_django' into 'master'
upgrade to django 2.2 See merge request ae/Sith!243
This commit is contained in:
commit
660a3161f5
@ -4,6 +4,7 @@ from __future__ import unicode_literals
|
||||
from django.db import migrations, models
|
||||
import django.core.validators
|
||||
import accounting.models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
@ -243,6 +244,7 @@ class Migration(migrations.Migration):
|
||||
verbose_name="accounting type",
|
||||
to="accounting.AccountingType",
|
||||
blank=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
),
|
||||
),
|
||||
],
|
||||
@ -267,6 +269,7 @@ class Migration(migrations.Migration):
|
||||
verbose_name="simplified accounting types",
|
||||
to="accounting.AccountingType",
|
||||
related_name="simplified_types",
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
@ -2,6 +2,7 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
@ -22,6 +23,7 @@ class Migration(migrations.Migration):
|
||||
verbose_name="invoice",
|
||||
to="core.SithFile",
|
||||
blank=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
@ -31,12 +33,14 @@ class Migration(migrations.Migration):
|
||||
verbose_name="journal",
|
||||
to="accounting.GeneralJournal",
|
||||
related_name="operations",
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="operation",
|
||||
name="linked_operation",
|
||||
field=models.OneToOneField(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
blank=True,
|
||||
to="accounting.Operation",
|
||||
null=True,
|
||||
@ -54,6 +58,7 @@ class Migration(migrations.Migration):
|
||||
verbose_name="simple type",
|
||||
to="accounting.SimplifiedAccountingType",
|
||||
blank=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
@ -63,6 +68,7 @@ class Migration(migrations.Migration):
|
||||
verbose_name="club account",
|
||||
to="accounting.ClubAccount",
|
||||
related_name="journals",
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
@ -72,20 +78,27 @@ class Migration(migrations.Migration):
|
||||
verbose_name="bank account",
|
||||
to="accounting.BankAccount",
|
||||
related_name="club_accounts",
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="clubaccount",
|
||||
name="club",
|
||||
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(
|
||||
model_name="bankaccount",
|
||||
name="club",
|
||||
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(
|
||||
|
@ -29,6 +29,7 @@ class Migration(migrations.Migration):
|
||||
related_name="labels",
|
||||
verbose_name="club account",
|
||||
to="accounting.ClubAccount",
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
@ -22,7 +22,7 @@
|
||||
#
|
||||
#
|
||||
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.urls import reverse
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.core import validators
|
||||
from django.db import models
|
||||
@ -110,7 +110,12 @@ class BankAccount(models.Model):
|
||||
name = models.CharField(_("name"), max_length=30)
|
||||
iban = models.CharField(_("iban"), 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:
|
||||
verbose_name = _("Bank account")
|
||||
@ -136,9 +141,17 @@ class BankAccount(models.Model):
|
||||
|
||||
class ClubAccount(models.Model):
|
||||
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(
|
||||
BankAccount, related_name="club_accounts", verbose_name=_("bank account")
|
||||
BankAccount,
|
||||
related_name="club_accounts",
|
||||
verbose_name=_("bank account"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
class Meta:
|
||||
@ -203,7 +216,11 @@ class GeneralJournal(models.Model):
|
||||
name = models.CharField(_("name"), max_length=40)
|
||||
closed = models.BooleanField(_("is closed"), default=False)
|
||||
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)
|
||||
effective_amount = CurrencyField(_("effective_amount"), default=0)
|
||||
@ -263,7 +280,11 @@ class Operation(models.Model):
|
||||
|
||||
number = models.IntegerField(_("number"))
|
||||
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"))
|
||||
date = models.DateField(_("date"))
|
||||
@ -282,6 +303,7 @@ class Operation(models.Model):
|
||||
verbose_name=_("invoice"),
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
done = models.BooleanField(_("is done"), default=False)
|
||||
simpleaccounting_type = models.ForeignKey(
|
||||
@ -290,6 +312,7 @@ class Operation(models.Model):
|
||||
verbose_name=_("simple type"),
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
accounting_type = models.ForeignKey(
|
||||
"AccountingType",
|
||||
@ -297,6 +320,7 @@ class Operation(models.Model):
|
||||
verbose_name=_("accounting type"),
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
label = models.ForeignKey(
|
||||
"Label",
|
||||
@ -328,6 +352,7 @@ class Operation(models.Model):
|
||||
null=True,
|
||||
blank=True,
|
||||
default=None,
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
class Meta:
|
||||
@ -487,6 +512,7 @@ class SimplifiedAccountingType(models.Model):
|
||||
AccountingType,
|
||||
related_name="simplified_types",
|
||||
verbose_name=_("simplified accounting types"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
class Meta:
|
||||
@ -518,7 +544,10 @@ class Label(models.Model):
|
||||
|
||||
name = models.CharField(_("label"), max_length=64)
|
||||
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:
|
||||
|
@ -20,14 +20,14 @@
|
||||
{% for k,v in statement.items() %}
|
||||
<tr>
|
||||
<td>{{ k }}</td>
|
||||
<td>{{ v }}</td>
|
||||
<td>{{ "%.2f" % v }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
|
||||
<p><strong>{% trans %}Amount: {% endtrans %}</strong>{{ object.amount }} €</p>
|
||||
<p><strong>{% trans %}Effective amount: {% endtrans %}</strong>{{ object.effective_amount }} €</p>
|
||||
<p><strong>{% trans %}Amount: {% endtrans %}</strong>{{ "%.2f" % object.amount }} €</p>
|
||||
<p><strong>{% trans %}Effective amount: {% endtrans %}</strong>{{ "%.2f" %object.effective_amount }} €</p>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
@ -18,12 +18,12 @@
|
||||
{% for k,v in dict['CREDIT'].items() %}
|
||||
<tr>
|
||||
<td>{{ k }}</td>
|
||||
<td>{{ v }}</td>
|
||||
<td>{{ "%.2f" % v }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% trans %}Total: {% endtrans %}{{ dict['CREDIT_sum'] }}
|
||||
{% trans %}Total: {% endtrans %}{{ "%.2f" % dict['CREDIT_sum'] }}
|
||||
|
||||
<h6>{% trans %}Debit{% endtrans %}</h6>
|
||||
<table>
|
||||
@ -37,19 +37,19 @@
|
||||
{% for k,v in dict['DEBIT'].items() %}
|
||||
<tr>
|
||||
<td>{{ k }}</td>
|
||||
<td>{{ v }}</td>
|
||||
<td>{{ "%.2f" % v }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% trans %}Total: {% endtrans %}{{ dict['DEBIT_sum'] }}
|
||||
{% trans %}Total: {% endtrans %}{{ "%.2f" % dict['DEBIT_sum'] }}
|
||||
{% endmacro %}
|
||||
|
||||
{% block content %}
|
||||
<h3>{% trans %}Statement by nature: {% endtrans %} {{ object.name }}</h3>
|
||||
|
||||
{% 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) }}
|
||||
<hr>
|
||||
{% endfor %}
|
||||
|
@ -28,14 +28,14 @@
|
||||
{% else %}
|
||||
<td></td>
|
||||
{% endif %}
|
||||
<td>{{ credit_statement[key] }}</td>
|
||||
<td>{{ "%.2f" % credit_statement[key] }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
|
||||
<p>Total : {{ total_credit }}</p>
|
||||
<p>Total : {{ "%.2f" % total_credit }}</p>
|
||||
|
||||
<h4>{% trans %}Debit{% endtrans %}</h4>
|
||||
|
||||
@ -56,13 +56,13 @@
|
||||
{% else %}
|
||||
<td></td>
|
||||
{% endif %}
|
||||
<td>{{ debit_statement[key] }}</td>
|
||||
<td>{{ "%.2f" % debit_statement[key] }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
|
||||
<p>Total : {{ total_debit }}</p>
|
||||
<p>Total : {{ "%.2f" % total_debit }}</p>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
@ -23,7 +23,7 @@
|
||||
#
|
||||
|
||||
from django.test import TestCase
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.urls import reverse
|
||||
from django.core.management import call_command
|
||||
from datetime import date
|
||||
|
||||
@ -272,30 +272,50 @@ class OperationTest(TestCase):
|
||||
|
||||
def test_nature_statement(self):
|
||||
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])
|
||||
)
|
||||
self.assertTrue(
|
||||
"bob (Troll Pench\\xc3\\xa9) : 3.00" in str(response_get.content)
|
||||
)
|
||||
self.assertContains(response, "bob (Troll Penché) : 3.00", status_code=200)
|
||||
|
||||
def test_person_statement(self):
|
||||
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])
|
||||
)
|
||||
self.assertTrue(
|
||||
"<td>3.00</td>" in str(response_get.content)
|
||||
and '<td><a href="/user/1/">S' Kia</a></td>'
|
||||
in str(response_get.content)
|
||||
self.assertContains(response, "Total : 5575.72", status_code=200)
|
||||
self.assertContains(response, "Total : 71.42")
|
||||
self.assertContains(
|
||||
response,
|
||||
"""
|
||||
<td><a href="/user/1/">S' Kia</a></td>
|
||||
|
||||
<td>3.00</td>""",
|
||||
)
|
||||
self.assertContains(
|
||||
response,
|
||||
"""
|
||||
<td><a href="/user/1/">S' Kia</a></td>
|
||||
|
||||
<td>823.00</td>""",
|
||||
)
|
||||
|
||||
def test_accounting_statement(self):
|
||||
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])
|
||||
)
|
||||
self.assertTrue(
|
||||
"<td>443 - Cr\\xc3\\xa9dit - Ce code n'existe pas</td>"
|
||||
in str(response_get.content)
|
||||
self.assertContains(
|
||||
response,
|
||||
"""
|
||||
<tr>
|
||||
<td>443 - Crédit - Ce code n'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>""",
|
||||
)
|
||||
|
@ -22,131 +22,133 @@
|
||||
#
|
||||
#
|
||||
|
||||
from django.conf.urls import url
|
||||
from django.urls import re_path
|
||||
|
||||
from accounting.views import *
|
||||
|
||||
urlpatterns = [
|
||||
# Accounting types
|
||||
url(
|
||||
re_path(
|
||||
r"^simple_type$",
|
||||
SimplifiedAccountingTypeListView.as_view(),
|
||||
name="simple_type_list",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^simple_type/create$",
|
||||
SimplifiedAccountingTypeCreateView.as_view(),
|
||||
name="simple_type_new",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^simple_type/(?P<type_id>[0-9]+)/edit$",
|
||||
SimplifiedAccountingTypeEditView.as_view(),
|
||||
name="simple_type_edit",
|
||||
),
|
||||
# Accounting types
|
||||
url(r"^type$", AccountingTypeListView.as_view(), name="type_list"),
|
||||
url(r"^type/create$", AccountingTypeCreateView.as_view(), name="type_new"),
|
||||
url(
|
||||
re_path(r"^type$", AccountingTypeListView.as_view(), name="type_list"),
|
||||
re_path(r"^type/create$", AccountingTypeCreateView.as_view(), name="type_new"),
|
||||
re_path(
|
||||
r"^type/(?P<type_id>[0-9]+)/edit$",
|
||||
AccountingTypeEditView.as_view(),
|
||||
name="type_edit",
|
||||
),
|
||||
# Bank accounts
|
||||
url(r"^$", BankAccountListView.as_view(), name="bank_list"),
|
||||
url(r"^bank/create$", BankAccountCreateView.as_view(), name="bank_new"),
|
||||
url(
|
||||
re_path(r"^$", BankAccountListView.as_view(), name="bank_list"),
|
||||
re_path(r"^bank/create$", BankAccountCreateView.as_view(), name="bank_new"),
|
||||
re_path(
|
||||
r"^bank/(?P<b_account_id>[0-9]+)$",
|
||||
BankAccountDetailView.as_view(),
|
||||
name="bank_details",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^bank/(?P<b_account_id>[0-9]+)/edit$",
|
||||
BankAccountEditView.as_view(),
|
||||
name="bank_edit",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^bank/(?P<b_account_id>[0-9]+)/delete$",
|
||||
BankAccountDeleteView.as_view(),
|
||||
name="bank_delete",
|
||||
),
|
||||
# Club accounts
|
||||
url(r"^club/create$", ClubAccountCreateView.as_view(), name="club_new"),
|
||||
url(
|
||||
re_path(r"^club/create$", ClubAccountCreateView.as_view(), name="club_new"),
|
||||
re_path(
|
||||
r"^club/(?P<c_account_id>[0-9]+)$",
|
||||
ClubAccountDetailView.as_view(),
|
||||
name="club_details",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^club/(?P<c_account_id>[0-9]+)/edit$",
|
||||
ClubAccountEditView.as_view(),
|
||||
name="club_edit",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^club/(?P<c_account_id>[0-9]+)/delete$",
|
||||
ClubAccountDeleteView.as_view(),
|
||||
name="club_delete",
|
||||
),
|
||||
# Journals
|
||||
url(r"^journal/create$", JournalCreateView.as_view(), name="journal_new"),
|
||||
url(
|
||||
re_path(r"^journal/create$", JournalCreateView.as_view(), name="journal_new"),
|
||||
re_path(
|
||||
r"^journal/(?P<j_id>[0-9]+)$",
|
||||
JournalDetailView.as_view(),
|
||||
name="journal_details",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^journal/(?P<j_id>[0-9]+)/edit$",
|
||||
JournalEditView.as_view(),
|
||||
name="journal_edit",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^journal/(?P<j_id>[0-9]+)/delete$",
|
||||
JournalDeleteView.as_view(),
|
||||
name="journal_delete",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^journal/(?P<j_id>[0-9]+)/statement/nature$",
|
||||
JournalNatureStatementView.as_view(),
|
||||
name="journal_nature_statement",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^journal/(?P<j_id>[0-9]+)/statement/person$",
|
||||
JournalPersonStatementView.as_view(),
|
||||
name="journal_person_statement",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^journal/(?P<j_id>[0-9]+)/statement/accounting$",
|
||||
JournalAccountingStatementView.as_view(),
|
||||
name="journal_accounting_statement",
|
||||
),
|
||||
# Operations
|
||||
url(
|
||||
re_path(
|
||||
r"^operation/create/(?P<j_id>[0-9]+)$",
|
||||
OperationCreateView.as_view(),
|
||||
name="op_new",
|
||||
),
|
||||
url(r"^operation/(?P<op_id>[0-9]+)$", OperationEditView.as_view(), name="op_edit"),
|
||||
url(
|
||||
re_path(
|
||||
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"
|
||||
),
|
||||
# Companies
|
||||
url(r"^company/list$", CompanyListView.as_view(), name="co_list"),
|
||||
url(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/list$", CompanyListView.as_view(), name="co_list"),
|
||||
re_path(r"^company/create$", CompanyCreateView.as_view(), name="co_new"),
|
||||
re_path(r"^company/(?P<co_id>[0-9]+)$", CompanyEditView.as_view(), name="co_edit"),
|
||||
# Labels
|
||||
url(r"^label/new$", LabelCreateView.as_view(), name="label_new"),
|
||||
url(
|
||||
re_path(r"^label/new$", LabelCreateView.as_view(), name="label_new"),
|
||||
re_path(
|
||||
r"^label/(?P<clubaccount_id>[0-9]+)$",
|
||||
LabelListView.as_view(),
|
||||
name="label_list",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
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$",
|
||||
LabelDeleteView.as_view(),
|
||||
name="label_delete",
|
||||
),
|
||||
# User account
|
||||
url(r"^refound/account$", RefoundAccountView.as_view(), name="refound_account"),
|
||||
re_path(r"^refound/account$", RefoundAccountView.as_view(), name="refound_account"),
|
||||
]
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
from django.views.generic import ListView, DetailView
|
||||
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.forms.models import modelform_factory
|
||||
from django.core.exceptions import PermissionDenied, ValidationError
|
||||
|
24
api/urls.py
24
api/urls.py
@ -22,35 +22,35 @@
|
||||
#
|
||||
#
|
||||
|
||||
from django.conf.urls import url, include
|
||||
from django.urls import re_path, include
|
||||
|
||||
from api.views import *
|
||||
from rest_framework import routers
|
||||
|
||||
# Router config
|
||||
router = routers.DefaultRouter()
|
||||
router.register(r"counter", CounterViewSet, base_name="api_counter")
|
||||
router.register(r"user", UserViewSet, base_name="api_user")
|
||||
router.register(r"club", ClubViewSet, base_name="api_club")
|
||||
router.register(r"group", GroupViewSet, base_name="api_group")
|
||||
router.register(r"counter", CounterViewSet, basename="api_counter")
|
||||
router.register(r"user", UserViewSet, basename="api_user")
|
||||
router.register(r"club", ClubViewSet, basename="api_club")
|
||||
router.register(r"group", GroupViewSet, basename="api_group")
|
||||
|
||||
# Launderette
|
||||
router.register(
|
||||
r"launderette/place", LaunderettePlaceViewSet, base_name="api_launderette_place"
|
||||
r"launderette/place", LaunderettePlaceViewSet, basename="api_launderette_place"
|
||||
)
|
||||
router.register(
|
||||
r"launderette/machine",
|
||||
LaunderetteMachineViewSet,
|
||||
base_name="api_launderette_machine",
|
||||
basename="api_launderette_machine",
|
||||
)
|
||||
router.register(
|
||||
r"launderette/token", LaunderetteTokenViewSet, base_name="api_launderette_token"
|
||||
r"launderette/token", LaunderetteTokenViewSet, basename="api_launderette_token"
|
||||
)
|
||||
|
||||
urlpatterns = [
|
||||
# API
|
||||
url(r"^", include(router.urls)),
|
||||
url(r"^login/", include("rest_framework.urls", namespace="rest_framework")),
|
||||
url(r"^markdown$", RenderMarkdown, name="api_markdown"),
|
||||
url(r"^mailings$", FetchMailingLists, name="mailings_fetch"),
|
||||
re_path(r"^", include(router.urls)),
|
||||
re_path(r"^login/", include("rest_framework.urls", namespace="rest_framework")),
|
||||
re_path(r"^markdown$", RenderMarkdown, name="api_markdown"),
|
||||
re_path(r"^mailings$", FetchMailingLists, name="mailings_fetch"),
|
||||
]
|
||||
|
@ -25,7 +25,7 @@
|
||||
from rest_framework.response import Response
|
||||
from rest_framework import viewsets
|
||||
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 core.views import can_view, can_edit
|
||||
@ -46,7 +46,7 @@ def check_if(obj, user, test):
|
||||
|
||||
|
||||
class ManageModelMixin:
|
||||
@detail_route()
|
||||
@action(detail=True)
|
||||
def id(self, request, pk=None):
|
||||
"""
|
||||
Get by id (api/v1/router/{pk}/id/)
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
from rest_framework import serializers
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.decorators import list_route
|
||||
from rest_framework.decorators import action
|
||||
|
||||
from counter.models import Counter
|
||||
|
||||
@ -51,7 +51,7 @@ class CounterViewSet(RightModelViewSet):
|
||||
serializer_class = CounterSerializer
|
||||
queryset = Counter.objects.all()
|
||||
|
||||
@list_route()
|
||||
@action(detail=False)
|
||||
def bar(self, request):
|
||||
"""
|
||||
Return all bars (api/v1/counter/bar/)
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
from rest_framework import serializers
|
||||
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
|
||||
|
||||
@ -96,7 +96,7 @@ class LaunderetteTokenViewSet(RightModelViewSet):
|
||||
serializer_class = LaunderetteTokenSerializer
|
||||
queryset = Token.objects.all()
|
||||
|
||||
@list_route()
|
||||
@action(detail=False)
|
||||
def washing(self, request):
|
||||
"""
|
||||
Return all washing tokens (api/v1/launderette/token/washing)
|
||||
@ -105,7 +105,7 @@ class LaunderetteTokenViewSet(RightModelViewSet):
|
||||
serializer = self.get_serializer(self.queryset, many=True)
|
||||
return Response(serializer.data)
|
||||
|
||||
@list_route()
|
||||
@action(detail=False)
|
||||
def drying(self, request):
|
||||
"""
|
||||
Return all drying tokens (api/v1/launderette/token/drying)
|
||||
@ -114,7 +114,7 @@ class LaunderetteTokenViewSet(RightModelViewSet):
|
||||
serializer = self.get_serializer(self.queryset, many=True)
|
||||
return Response(serializer.data)
|
||||
|
||||
@list_route()
|
||||
@action(detail=False)
|
||||
def avaliable(self, request):
|
||||
"""
|
||||
Return all avaliable tokens (api/v1/launderette/token/avaliable)
|
||||
@ -125,7 +125,7 @@ class LaunderetteTokenViewSet(RightModelViewSet):
|
||||
serializer = self.get_serializer(self.queryset, many=True)
|
||||
return Response(serializer.data)
|
||||
|
||||
@list_route()
|
||||
@action(detail=False)
|
||||
def unavaliable(self, request):
|
||||
"""
|
||||
Return all unavaliable tokens (api/v1/launderette/token/unavaliable)
|
||||
|
@ -26,7 +26,7 @@ import datetime
|
||||
|
||||
from rest_framework import serializers
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.decorators import list_route
|
||||
from rest_framework.decorators import action
|
||||
|
||||
from core.models import User
|
||||
|
||||
@ -57,7 +57,7 @@ class UserViewSet(RightModelViewSet):
|
||||
serializer_class = UserSerializer
|
||||
queryset = User.objects.filter(is_active=True)
|
||||
|
||||
@list_route()
|
||||
@action(detail=False)
|
||||
def birthday(self, request):
|
||||
"""
|
||||
Return all users born today (api/v1/user/birstdays)
|
||||
|
@ -66,7 +66,7 @@ class MailingForm(forms.Form):
|
||||
super(MailingForm, self).__init__(*args, **kwargs)
|
||||
|
||||
self.fields["action"] = forms.TypedChoiceField(
|
||||
(
|
||||
choices=(
|
||||
(self.ACTION_NEW_MAILING, _("New Mailing")),
|
||||
(self.ACTION_NEW_SUBSCRIPTION, _("Subscribe")),
|
||||
(self.ACTION_REMOVE_SUBSCRIPTION, _("Remove")),
|
||||
@ -159,13 +159,13 @@ class MailingForm(forms.Form):
|
||||
|
||||
class SellingsFormBase(forms.Form):
|
||||
begin_date = forms.DateTimeField(
|
||||
["%Y-%m-%d %H:%M:%S"],
|
||||
input_formats=["%Y-%m-%d %H:%M:%S"],
|
||||
label=_("Begin date"),
|
||||
required=False,
|
||||
widget=SelectDateTime,
|
||||
)
|
||||
end_date = forms.DateTimeField(
|
||||
["%Y-%m-%d %H:%M:%S"],
|
||||
input_formats=["%Y-%m-%d %H:%M:%S"],
|
||||
label=_("End date"),
|
||||
required=False,
|
||||
widget=SelectDateTime,
|
||||
|
@ -3,6 +3,7 @@ from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.core.validators
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
@ -90,7 +91,10 @@ class Migration(migrations.Migration):
|
||||
(
|
||||
"club",
|
||||
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,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
@ -3,6 +3,7 @@ from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
from django.conf import settings
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
@ -18,6 +19,7 @@ class Migration(migrations.Migration):
|
||||
model_name="membership",
|
||||
name="user",
|
||||
field=models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
verbose_name="user",
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
related_name="membership",
|
||||
@ -34,6 +36,7 @@ class Migration(migrations.Migration):
|
||||
model_name="club",
|
||||
name="home",
|
||||
field=models.OneToOneField(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
blank=True,
|
||||
null=True,
|
||||
related_name="home_of_club",
|
||||
@ -45,14 +48,21 @@ class Migration(migrations.Migration):
|
||||
model_name="club",
|
||||
name="owner_group",
|
||||
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(
|
||||
model_name="club",
|
||||
name="parent",
|
||||
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(
|
||||
|
@ -3,6 +3,7 @@ from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
from django.conf import settings
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
@ -14,6 +15,7 @@ class Migration(migrations.Migration):
|
||||
model_name="membership",
|
||||
name="user",
|
||||
field=models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
verbose_name="user",
|
||||
related_name="memberships",
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
|
@ -5,6 +5,7 @@ from django.db import migrations, models
|
||||
from django.conf import settings
|
||||
import re
|
||||
import django.core.validators
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
@ -51,12 +52,16 @@ class Migration(migrations.Migration):
|
||||
(
|
||||
"club",
|
||||
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",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
null=True,
|
||||
verbose_name="moderator",
|
||||
related_name="moderated_mailings",
|
||||
@ -84,6 +89,7 @@ class Migration(migrations.Migration):
|
||||
(
|
||||
"mailing",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
verbose_name="Mailing",
|
||||
related_name="subscriptions",
|
||||
to="club.Mailing",
|
||||
@ -92,6 +98,7 @@ class Migration(migrations.Migration):
|
||||
(
|
||||
"user",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
null=True,
|
||||
verbose_name="User",
|
||||
related_name="mailing_subscriptions",
|
||||
|
@ -5,6 +5,7 @@ from django.db import migrations, models
|
||||
|
||||
from club.models import Club
|
||||
from core.operations import PsqlRunOnly
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
def generate_club_pages(apps, schema_editor):
|
||||
@ -31,7 +32,11 @@ class Migration(migrations.Migration):
|
||||
model_name="club",
|
||||
name="page",
|
||||
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(
|
||||
|
@ -3,6 +3,7 @@ from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
import club.models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
@ -14,6 +15,7 @@ class Migration(migrations.Migration):
|
||||
model_name="club",
|
||||
name="owner_group",
|
||||
field=models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
default=club.models.Club.get_default_owner_group,
|
||||
related_name="owned_club",
|
||||
to="core.Group",
|
||||
|
@ -29,7 +29,7 @@ from django.conf import settings
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.core.exceptions import ValidationError, ObjectDoesNotExist
|
||||
from django.db import transaction
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.urls import reverse
|
||||
from django.utils import timezone
|
||||
from django.core.validators import RegexValidator, validate_email
|
||||
from django.utils.functional import cached_property
|
||||
@ -46,7 +46,9 @@ class Club(models.Model):
|
||||
|
||||
id = models.AutoField(primary_key=True, db_index=True)
|
||||
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"),
|
||||
max_length=30,
|
||||
@ -75,7 +77,10 @@ class Club(models.Model):
|
||||
return settings.SITH_GROUP_ROOT_ID
|
||||
|
||||
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(
|
||||
Group, related_name="editable_club", blank=True
|
||||
@ -91,7 +96,9 @@ class Club(models.Model):
|
||||
blank=True,
|
||||
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:
|
||||
ordering = ["name", "unix_name"]
|
||||
@ -183,8 +190,8 @@ class Club(models.Model):
|
||||
name=settings.SITH_MAIN_MEMBERS_GROUP
|
||||
).first()
|
||||
self.make_home()
|
||||
self.home.edit_groups = [board]
|
||||
self.home.view_groups = [member, subscribers]
|
||||
self.home.edit_groups.set([board])
|
||||
self.home.view_groups.set([member, subscribers])
|
||||
self.home.save()
|
||||
self.make_page()
|
||||
|
||||
@ -261,9 +268,15 @@ class Membership(models.Model):
|
||||
related_name="memberships",
|
||||
null=False,
|
||||
blank=False,
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
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)
|
||||
end_date = models.DateField(_("end date"), null=True, blank=True)
|
||||
@ -317,7 +330,12 @@ class Mailing(models.Model):
|
||||
"""
|
||||
|
||||
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 address"),
|
||||
@ -334,7 +352,11 @@ class Mailing(models.Model):
|
||||
)
|
||||
is_moderated = models.BooleanField(_("is moderated"), default=False)
|
||||
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):
|
||||
@ -409,6 +431,7 @@ class MailingSubscription(models.Model):
|
||||
related_name="subscriptions",
|
||||
null=False,
|
||||
blank=False,
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
user = models.ForeignKey(
|
||||
User,
|
||||
@ -416,6 +439,7 @@ class MailingSubscription(models.Model):
|
||||
related_name="mailing_subscriptions",
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
email = models.EmailField(_("Email address"), blank=False, null=False)
|
||||
|
||||
|
@ -26,7 +26,7 @@ from django.conf import settings
|
||||
from django.test import TestCase
|
||||
from django.utils import timezone, html
|
||||
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.exceptions import ValidationError, NON_FIELD_ERRORS
|
||||
|
||||
|
56
club/urls.py
56
club/urls.py
@ -23,80 +23,88 @@
|
||||
#
|
||||
#
|
||||
|
||||
from django.conf.urls import url
|
||||
from django.urls import re_path
|
||||
|
||||
from club.views import *
|
||||
|
||||
urlpatterns = [
|
||||
url(r"^$", ClubListView.as_view(), name="club_list"),
|
||||
url(r"^new$", ClubCreateView.as_view(), name="club_new"),
|
||||
url(r"^stats$", ClubStatView.as_view(), name="club_stats"),
|
||||
url(r"^(?P<club_id>[0-9]+)/$", ClubView.as_view(), name="club_view"),
|
||||
url(
|
||||
re_path(r"^$", ClubListView.as_view(), name="club_list"),
|
||||
re_path(r"^new$", ClubCreateView.as_view(), name="club_new"),
|
||||
re_path(r"^stats$", ClubStatView.as_view(), name="club_stats"),
|
||||
re_path(r"^(?P<club_id>[0-9]+)/$", ClubView.as_view(), name="club_view"),
|
||||
re_path(
|
||||
r"^(?P<club_id>[0-9]+)/rev/(?P<rev_id>[0-9]+)/$",
|
||||
ClubRevView.as_view(),
|
||||
name="club_view_rev",
|
||||
),
|
||||
url(r"^(?P<club_id>[0-9]+)/hist$", ClubPageHistView.as_view(), name="club_hist"),
|
||||
url(r"^(?P<club_id>[0-9]+)/edit$", ClubEditView.as_view(), name="club_edit"),
|
||||
url(
|
||||
re_path(
|
||||
r"^(?P<club_id>[0-9]+)/hist$", ClubPageHistView.as_view(), name="club_hist"
|
||||
),
|
||||
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$",
|
||||
ClubPageEditView.as_view(),
|
||||
name="club_edit_page",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^(?P<club_id>[0-9]+)/members$", ClubMembersView.as_view(), name="club_members"
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^(?P<club_id>[0-9]+)/elderlies$",
|
||||
ClubOldMembersView.as_view(),
|
||||
name="club_old_members",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^(?P<club_id>[0-9]+)/sellings$",
|
||||
ClubSellingView.as_view(),
|
||||
name="club_sellings",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^(?P<club_id>[0-9]+)/sellings/csv$",
|
||||
ClubSellingCSVView.as_view(),
|
||||
name="sellings_csv",
|
||||
),
|
||||
url(r"^(?P<club_id>[0-9]+)/prop$", ClubEditPropView.as_view(), name="club_prop"),
|
||||
url(r"^(?P<club_id>[0-9]+)/tools$", ClubToolsView.as_view(), name="tools"),
|
||||
url(r"^(?P<club_id>[0-9]+)/mailing$", ClubMailingView.as_view(), name="mailing"),
|
||||
url(
|
||||
re_path(
|
||||
r"^(?P<club_id>[0-9]+)/prop$", ClubEditPropView.as_view(), name="club_prop"
|
||||
),
|
||||
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$",
|
||||
MailingAutoGenerationView.as_view(),
|
||||
name="mailing_generate",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^(?P<mailing_id>[0-9]+)/mailing/delete$",
|
||||
MailingDeleteView.as_view(),
|
||||
name="mailing_delete",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^(?P<mailing_subscription_id>[0-9]+)/mailing/delete/subscription$",
|
||||
MailingSubscriptionDeleteView.as_view(),
|
||||
name="mailing_subscription_delete",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^membership/(?P<membership_id>[0-9]+)/set_old$",
|
||||
MembershipSetOldView.as_view(),
|
||||
name="membership_set_old",
|
||||
),
|
||||
url(r"^(?P<club_id>[0-9]+)/poster$", PosterListView.as_view(), name="poster_list"),
|
||||
url(
|
||||
re_path(
|
||||
r"^(?P<club_id>[0-9]+)/poster$", PosterListView.as_view(), name="poster_list"
|
||||
),
|
||||
re_path(
|
||||
r"^(?P<club_id>[0-9]+)/poster/create$",
|
||||
PosterCreateView.as_view(),
|
||||
name="poster_create",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^(?P<club_id>[0-9]+)/poster/(?P<poster_id>[0-9]+)/edit$",
|
||||
PosterEditView.as_view(),
|
||||
name="poster_edit",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^(?P<club_id>[0-9]+)/poster/(?P<poster_id>[0-9]+)/delete$",
|
||||
PosterDeleteView.as_view(),
|
||||
name="poster_delete",
|
||||
|
@ -31,7 +31,7 @@ from django.views.generic.edit import DeleteView
|
||||
from django.views.generic.detail import SingleObjectMixin
|
||||
from django.views.generic.edit import UpdateView, CreateView
|
||||
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.translation import ugettext_lazy as _
|
||||
from django.utils.translation import ugettext as _t
|
||||
|
@ -3,6 +3,7 @@ from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
from django.conf import settings
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
@ -50,6 +51,7 @@ class Migration(migrations.Migration):
|
||||
(
|
||||
"author",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="owned_news",
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
verbose_name="author",
|
||||
@ -58,12 +60,16 @@ class Migration(migrations.Migration):
|
||||
(
|
||||
"club",
|
||||
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",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="moderated_news",
|
||||
null=True,
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
@ -99,7 +105,10 @@ class Migration(migrations.Migration):
|
||||
(
|
||||
"news",
|
||||
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",
|
||||
),
|
||||
),
|
||||
],
|
||||
|
@ -3,6 +3,7 @@ from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
from django.conf import settings
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
@ -56,6 +57,7 @@ class Migration(migrations.Migration):
|
||||
(
|
||||
"author",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
verbose_name="author",
|
||||
related_name="owned_weekmail_articles",
|
||||
@ -64,6 +66,7 @@ class Migration(migrations.Migration):
|
||||
(
|
||||
"club",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
to="club.Club",
|
||||
verbose_name="club",
|
||||
related_name="weekmail_articles",
|
||||
@ -72,6 +75,7 @@ class Migration(migrations.Migration):
|
||||
(
|
||||
"weekmail",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
to="com.Weekmail",
|
||||
verbose_name="weekmail",
|
||||
related_name="articles",
|
||||
|
@ -4,6 +4,7 @@ from __future__ import unicode_literals
|
||||
from django.db import migrations, models
|
||||
import django.utils.timezone
|
||||
from django.conf import settings
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
@ -48,12 +49,16 @@ class Migration(migrations.Migration):
|
||||
(
|
||||
"club",
|
||||
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",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
verbose_name="moderator",
|
||||
blank=True,
|
||||
null=True,
|
||||
|
@ -28,7 +28,7 @@ from django.db import models, transaction
|
||||
from django.db.models import Q
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils import timezone
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.urls import reverse
|
||||
from django.conf import settings
|
||||
from django.contrib.staticfiles.templatetags.staticfiles import static
|
||||
from django.core.mail import EmailMultiAlternatives
|
||||
@ -71,13 +71,22 @@ class News(models.Model):
|
||||
type = models.CharField(
|
||||
_("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(
|
||||
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)
|
||||
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):
|
||||
@ -138,7 +147,12 @@ class NewsDate(models.Model):
|
||||
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)
|
||||
end_date = models.DateTimeField(_("end_date"), null=True, blank=True)
|
||||
|
||||
@ -230,15 +244,25 @@ class Weekmail(models.Model):
|
||||
|
||||
class WeekmailArticle(models.Model):
|
||||
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)
|
||||
content = models.TextField(_("content"))
|
||||
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, 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)
|
||||
|
||||
@ -271,7 +295,11 @@ class Poster(models.Model):
|
||||
)
|
||||
file = models.ImageField(_("file"), null=False, upload_to="com/posters")
|
||||
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")
|
||||
date_begin = models.DateTimeField(blank=False, null=False, default=timezone.now)
|
||||
@ -286,6 +314,7 @@ class Poster(models.Model):
|
||||
verbose_name=_("moderator"),
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
from django.test import TestCase
|
||||
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.utils import html
|
||||
from django.utils.translation import ugettext as _
|
||||
@ -62,7 +62,7 @@ class ComTest(TestCase):
|
||||
self.com_group = RealGroup.objects.filter(
|
||||
id=settings.SITH_GROUP_COM_ADMIN_ID
|
||||
).first()
|
||||
self.skia.groups = [self.com_group]
|
||||
self.skia.groups.set([self.com_group])
|
||||
self.skia.save()
|
||||
self.client.login(username=self.skia.username, password="plop")
|
||||
|
||||
|
66
com/urls.py
66
com/urls.py
@ -22,97 +22,103 @@
|
||||
#
|
||||
#
|
||||
|
||||
from django.conf.urls import url
|
||||
from django.urls import re_path
|
||||
|
||||
from com.views import *
|
||||
from club.views import MailingDeleteView
|
||||
|
||||
urlpatterns = [
|
||||
url(r"^sith/edit/alert$", AlertMsgEditView.as_view(), name="alert_edit"),
|
||||
url(r"^sith/edit/info$", InfoMsgEditView.as_view(), name="info_edit"),
|
||||
url(
|
||||
re_path(r"^sith/edit/alert$", AlertMsgEditView.as_view(), name="alert_edit"),
|
||||
re_path(r"^sith/edit/info$", InfoMsgEditView.as_view(), name="info_edit"),
|
||||
re_path(
|
||||
r"^sith/edit/weekmail_destinations$",
|
||||
WeekmailDestinationEditView.as_view(),
|
||||
name="weekmail_destinations",
|
||||
),
|
||||
url(r"^weekmail$", WeekmailEditView.as_view(), name="weekmail"),
|
||||
url(r"^weekmail/preview$", WeekmailPreviewView.as_view(), name="weekmail_preview"),
|
||||
url(
|
||||
re_path(r"^weekmail$", WeekmailEditView.as_view(), name="weekmail"),
|
||||
re_path(
|
||||
r"^weekmail/preview$", WeekmailPreviewView.as_view(), name="weekmail_preview"
|
||||
),
|
||||
re_path(
|
||||
r"^weekmail/new_article$",
|
||||
WeekmailArticleCreateView.as_view(),
|
||||
name="weekmail_article",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^weekmail/article/(?P<article_id>[0-9]+)/delete$",
|
||||
WeekmailArticleDeleteView.as_view(),
|
||||
name="weekmail_article_delete",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^weekmail/article/(?P<article_id>[0-9]+)/edit$",
|
||||
WeekmailArticleEditView.as_view(),
|
||||
name="weekmail_article_edit",
|
||||
),
|
||||
url(r"^news$", NewsListView.as_view(), name="news_list"),
|
||||
url(r"^news/admin$", NewsAdminListView.as_view(), name="news_admin_list"),
|
||||
url(r"^news/create$", NewsCreateView.as_view(), name="news_new"),
|
||||
url(
|
||||
re_path(r"^news$", NewsListView.as_view(), name="news_list"),
|
||||
re_path(r"^news/admin$", NewsAdminListView.as_view(), name="news_admin_list"),
|
||||
re_path(r"^news/create$", NewsCreateView.as_view(), name="news_new"),
|
||||
re_path(
|
||||
r"^news/(?P<news_id>[0-9]+)/delete$",
|
||||
NewsDeleteView.as_view(),
|
||||
name="news_delete",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^news/(?P<news_id>[0-9]+)/moderate$",
|
||||
NewsModerateView.as_view(),
|
||||
name="news_moderate",
|
||||
),
|
||||
url(r"^news/(?P<news_id>[0-9]+)/edit$", NewsEditView.as_view(), name="news_edit"),
|
||||
url(r"^news/(?P<news_id>[0-9]+)$", NewsDetailView.as_view(), name="news_detail"),
|
||||
url(r"^mailings$", MailingListAdminView.as_view(), name="mailing_admin"),
|
||||
url(
|
||||
re_path(
|
||||
r"^news/(?P<news_id>[0-9]+)/edit$", NewsEditView.as_view(), name="news_edit"
|
||||
),
|
||||
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$",
|
||||
MailingModerateView.as_view(),
|
||||
name="mailing_moderate",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^mailings/(?P<mailing_id>[0-9]+)/delete$",
|
||||
MailingDeleteView.as_view(redirect_page="com:mailing_admin"),
|
||||
name="mailing_delete",
|
||||
),
|
||||
url(r"^poster$", PosterListView.as_view(), name="poster_list"),
|
||||
url(r"^poster/create$", PosterCreateView.as_view(), name="poster_create"),
|
||||
url(
|
||||
re_path(r"^poster$", PosterListView.as_view(), name="poster_list"),
|
||||
re_path(r"^poster/create$", PosterCreateView.as_view(), name="poster_create"),
|
||||
re_path(
|
||||
r"^poster/(?P<poster_id>[0-9]+)/edit$",
|
||||
PosterEditView.as_view(),
|
||||
name="poster_edit",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^poster/(?P<poster_id>[0-9]+)/delete$",
|
||||
PosterDeleteView.as_view(),
|
||||
name="poster_delete",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^poster/moderate$",
|
||||
PosterModerateListView.as_view(),
|
||||
name="poster_moderate_list",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^poster/(?P<object_id>[0-9]+)/moderate$",
|
||||
PosterModerateView.as_view(),
|
||||
name="poster_moderate",
|
||||
),
|
||||
url(r"^screen$", ScreenListView.as_view(), name="screen_list"),
|
||||
url(r"^screen/create$", ScreenCreateView.as_view(), name="screen_create"),
|
||||
url(
|
||||
re_path(r"^screen$", ScreenListView.as_view(), name="screen_list"),
|
||||
re_path(r"^screen/create$", ScreenCreateView.as_view(), name="screen_create"),
|
||||
re_path(
|
||||
r"^screen/(?P<screen_id>[0-9]+)/slideshow$",
|
||||
ScreenSlideshowView.as_view(),
|
||||
name="screen_slideshow",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^screen/(?P<screen_id>[0-9]+)/edit$",
|
||||
ScreenEditView.as_view(),
|
||||
name="screen_edit",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^screen/(?P<screen_id>[0-9]+)/delete$",
|
||||
ScreenDeleteView.as_view(),
|
||||
name="screen_delete",
|
||||
|
15
com/views.py
15
com/views.py
@ -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.detail import SingleObjectMixin
|
||||
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.utils import timezone
|
||||
from django.conf import settings
|
||||
@ -74,14 +74,14 @@ class PosterForm(forms.ModelForm):
|
||||
widgets = {"screens": forms.CheckboxSelectMultiple}
|
||||
|
||||
date_begin = forms.DateTimeField(
|
||||
["%Y-%m-%d %H:%M:%S"],
|
||||
input_formats=["%Y-%m-%d %H:%M:%S"],
|
||||
label=_("Start date"),
|
||||
widget=SelectDateTime,
|
||||
required=True,
|
||||
initial=timezone.now().strftime("%Y-%m-%d %H:%M:%S"),
|
||||
)
|
||||
date_end = forms.DateTimeField(
|
||||
["%Y-%m-%d %H:%M:%S"],
|
||||
input_formats=["%Y-%m-%d %H:%M:%S"],
|
||||
label=_("End date"),
|
||||
widget=SelectDateTime,
|
||||
required=False,
|
||||
@ -200,19 +200,22 @@ class NewsForm(forms.ModelForm):
|
||||
}
|
||||
|
||||
start_date = forms.DateTimeField(
|
||||
["%Y-%m-%d %H:%M:%S"],
|
||||
input_formats=["%Y-%m-%d %H:%M:%S"],
|
||||
label=_("Start date"),
|
||||
widget=SelectDateTime,
|
||||
required=False,
|
||||
)
|
||||
end_date = forms.DateTimeField(
|
||||
["%Y-%m-%d %H:%M:%S"],
|
||||
input_formats=["%Y-%m-%d %H:%M:%S"],
|
||||
label=_("End date"),
|
||||
widget=SelectDateTime,
|
||||
required=False,
|
||||
)
|
||||
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)
|
||||
|
||||
|
@ -142,18 +142,18 @@ class Command(BaseCommand):
|
||||
g.save()
|
||||
c = Counter(id=b[0], name=b[1], club=bar_club, type="BAR")
|
||||
c.save()
|
||||
c.edit_groups = [g]
|
||||
c.save()
|
||||
g.editable_counters.add(c)
|
||||
g.save()
|
||||
self.reset_index("counter")
|
||||
Counter(name="Eboutic", club=main_club, type="EBOUTIC").save()
|
||||
Counter(name="AE", club=main_club, type="OFFICE").save()
|
||||
|
||||
home_root.view_groups = [
|
||||
Group.objects.filter(name=settings.SITH_MAIN_MEMBERS_GROUP).first()
|
||||
]
|
||||
club_root.view_groups = [
|
||||
Group.objects.filter(name=settings.SITH_MAIN_MEMBERS_GROUP).first()
|
||||
]
|
||||
home_root.view_groups.set(
|
||||
[Group.objects.filter(name=settings.SITH_MAIN_MEMBERS_GROUP).first()]
|
||||
)
|
||||
club_root.view_groups.set(
|
||||
[Group.objects.filter(name=settings.SITH_MAIN_MEMBERS_GROUP).first()]
|
||||
)
|
||||
home_root.save()
|
||||
club_root.save()
|
||||
|
||||
@ -163,7 +163,7 @@ class Command(BaseCommand):
|
||||
p = Page(name="Index")
|
||||
p.set_lock(root)
|
||||
p.save()
|
||||
p.view_groups = [settings.SITH_GROUP_PUBLIC_ID]
|
||||
p.view_groups.set([settings.SITH_GROUP_PUBLIC_ID])
|
||||
p.set_lock(root)
|
||||
p.save()
|
||||
PageRev(
|
||||
@ -178,7 +178,7 @@ Welcome to the wiki page!
|
||||
p = Page(name="services")
|
||||
p.set_lock(root)
|
||||
p.save()
|
||||
p.view_groups = [settings.SITH_GROUP_PUBLIC_ID]
|
||||
p.view_groups.set([settings.SITH_GROUP_PUBLIC_ID])
|
||||
p.set_lock(root)
|
||||
PageRev(
|
||||
page=p,
|
||||
@ -297,9 +297,13 @@ Welcome to the wiki page!
|
||||
counter.view_groups = [
|
||||
Group.objects.filter(name=settings.SITH_MAIN_MEMBERS_GROUP).first().id
|
||||
]
|
||||
counter.groups = [
|
||||
Group.objects.filter(id=settings.SITH_GROUP_COUNTER_ADMIN_ID).first().id
|
||||
]
|
||||
counter.groups.set(
|
||||
[
|
||||
Group.objects.filter(id=settings.SITH_GROUP_COUNTER_ADMIN_ID)
|
||||
.first()
|
||||
.id
|
||||
]
|
||||
)
|
||||
counter.save()
|
||||
# Adding user Comptable
|
||||
comptable = User(
|
||||
@ -316,11 +320,13 @@ Welcome to the wiki page!
|
||||
comptable.view_groups = [
|
||||
Group.objects.filter(name=settings.SITH_MAIN_MEMBERS_GROUP).first().id
|
||||
]
|
||||
comptable.groups = [
|
||||
Group.objects.filter(id=settings.SITH_GROUP_ACCOUNTING_ADMIN_ID)
|
||||
.first()
|
||||
.id
|
||||
]
|
||||
comptable.groups.set(
|
||||
[
|
||||
Group.objects.filter(id=settings.SITH_GROUP_ACCOUNTING_ADMIN_ID)
|
||||
.first()
|
||||
.id
|
||||
]
|
||||
)
|
||||
comptable.save()
|
||||
# Adding user Guy
|
||||
u = User(
|
||||
@ -359,11 +365,11 @@ Welcome to the wiki page!
|
||||
PageRev(
|
||||
page=p, title="Aide sur la syntaxe", author=skia, content=rm.read()
|
||||
).save()
|
||||
p.view_groups = [settings.SITH_GROUP_PUBLIC_ID]
|
||||
p.view_groups.set([settings.SITH_GROUP_PUBLIC_ID])
|
||||
p.save(force_lock=True)
|
||||
p = Page(name="Services")
|
||||
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)
|
||||
PageRev(
|
||||
page=p,
|
||||
@ -842,9 +848,9 @@ Welcome to the wiki page!
|
||||
)
|
||||
comunity.set_password("plop")
|
||||
comunity.save()
|
||||
comunity.groups = [
|
||||
Group.objects.filter(name="Communication admin").first().id
|
||||
]
|
||||
comunity.groups.set(
|
||||
[Group.objects.filter(name="Communication admin").first().id]
|
||||
)
|
||||
comunity.save()
|
||||
Membership(
|
||||
user=comunity,
|
||||
@ -862,7 +868,7 @@ Welcome to the wiki page!
|
||||
)
|
||||
tutu.set_password("plop")
|
||||
tutu.save()
|
||||
tutu.groups = [settings.SITH_GROUP_PEDAGOGY_ADMIN_ID]
|
||||
tutu.groups.set([settings.SITH_GROUP_PEDAGOGY_ADMIN_ID])
|
||||
tutu.save()
|
||||
|
||||
# Adding subscription for sli
|
||||
|
@ -25,7 +25,7 @@
|
||||
import os
|
||||
import re
|
||||
from mistune import Renderer, InlineGrammar, InlineLexer, Markdown, escape, escape_link
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.urls import reverse
|
||||
|
||||
|
||||
class SithRenderer(Renderer):
|
||||
|
@ -37,7 +37,7 @@ AnonymousUser = getattr(importlib.import_module(module), klass)
|
||||
def get_cached_user(request):
|
||||
if not hasattr(request, "_cached_user"):
|
||||
user = get_user(request)
|
||||
if user.is_anonymous():
|
||||
if user.is_anonymous:
|
||||
user = AnonymousUser(request)
|
||||
|
||||
request._cached_user = user
|
||||
|
@ -8,6 +8,7 @@ import django.core.validators
|
||||
import core.models
|
||||
import phonenumber_field.modelfields
|
||||
from django.conf import settings
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
@ -276,6 +277,7 @@ class Migration(migrations.Migration):
|
||||
(
|
||||
"group_ptr",
|
||||
models.OneToOneField(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
primary_key=True,
|
||||
parent_link=True,
|
||||
serialize=False,
|
||||
@ -329,6 +331,7 @@ class Migration(migrations.Migration):
|
||||
(
|
||||
"owner_group",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
default=1,
|
||||
related_name="owned_page",
|
||||
verbose_name="owner group",
|
||||
@ -390,10 +393,19 @@ class Migration(migrations.Migration):
|
||||
(
|
||||
"author",
|
||||
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"]},
|
||||
),
|
||||
@ -420,7 +432,9 @@ class Migration(migrations.Migration):
|
||||
(
|
||||
"user",
|
||||
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",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
verbose_name="owner",
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
related_name="owned_files",
|
||||
@ -477,6 +492,7 @@ class Migration(migrations.Migration):
|
||||
(
|
||||
"parent",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
null=True,
|
||||
related_name="children",
|
||||
verbose_name="parent",
|
||||
@ -512,6 +528,7 @@ class Migration(migrations.Migration):
|
||||
model_name="user",
|
||||
name="home",
|
||||
field=models.OneToOneField(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
blank=True,
|
||||
null=True,
|
||||
related_name="home_of",
|
||||
|
@ -3,6 +3,7 @@ from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
from django.conf import settings
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
@ -21,6 +22,7 @@ class Migration(migrations.Migration):
|
||||
model_name="page",
|
||||
name="lock_user",
|
||||
field=models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
verbose_name="lock user",
|
||||
default=None,
|
||||
blank=True,
|
||||
|
@ -4,6 +4,7 @@ from __future__ import unicode_literals
|
||||
from django.db import migrations, models
|
||||
from django.conf import settings
|
||||
import django.utils.timezone
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
@ -48,7 +49,9 @@ class Migration(migrations.Migration):
|
||||
(
|
||||
"user",
|
||||
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,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
@ -3,6 +3,7 @@ from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
from django.conf import settings
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
@ -14,6 +15,7 @@ class Migration(migrations.Migration):
|
||||
model_name="sithfile",
|
||||
name="moderator",
|
||||
field=models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="moderated_files",
|
||||
verbose_name="owner",
|
||||
default=0,
|
||||
|
@ -3,6 +3,7 @@ from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
from django.conf import settings
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
@ -14,6 +15,7 @@ class Migration(migrations.Migration):
|
||||
model_name="sithfile",
|
||||
name="moderator",
|
||||
field=models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="moderated_files",
|
||||
blank=True,
|
||||
null=True,
|
||||
|
@ -3,6 +3,7 @@ from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
from django.conf import settings
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
@ -35,7 +36,9 @@ class Migration(migrations.Migration):
|
||||
model_name="preferences",
|
||||
name="user",
|
||||
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,
|
||||
),
|
||||
),
|
||||
]
|
||||
|
@ -4,6 +4,7 @@ from __future__ import unicode_literals
|
||||
from django.db import migrations, models
|
||||
from django.conf import settings
|
||||
import django.utils.timezone
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
@ -33,7 +34,9 @@ class Migration(migrations.Migration):
|
||||
(
|
||||
"user",
|
||||
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,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
@ -3,6 +3,7 @@ from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
import core.models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
@ -14,6 +15,7 @@ class Migration(migrations.Migration):
|
||||
model_name="page",
|
||||
name="owner_group",
|
||||
field=models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
verbose_name="owner group",
|
||||
default=core.models.Page.get_default_owner_group,
|
||||
related_name="owned_page",
|
||||
|
27
core/migrations/0033_auto_20191006_0049.py
Normal file
27
core/migrations/0033_auto_20191006_0049.py
Normal 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())],
|
||||
),
|
||||
]
|
@ -38,7 +38,7 @@ from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils import timezone
|
||||
from django.core import validators
|
||||
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.db import transaction
|
||||
from django.contrib.staticfiles.storage import staticfiles_storage
|
||||
@ -743,7 +743,9 @@ class AnonymousUser(AuthAnonymousUser):
|
||||
|
||||
|
||||
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(
|
||||
_("do you want to receive the weekmail"), default=False
|
||||
)
|
||||
@ -777,7 +779,12 @@ def get_thumbnail_directory(instance, filename):
|
||||
class SithFile(models.Model):
|
||||
name = models.CharField(_("file name"), max_length=256, blank=False)
|
||||
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(
|
||||
upload_to=get_directory,
|
||||
@ -800,7 +807,12 @@ class SithFile(models.Model):
|
||||
null=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(
|
||||
Group, related_name="editable_files", verbose_name=_("edit group"), blank=True
|
||||
)
|
||||
@ -818,6 +830,7 @@ class SithFile(models.Model):
|
||||
verbose_name=_("owner"),
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
asked_for_removal = models.BooleanField(_("asked for removal"), default=False)
|
||||
is_in_sas = models.BooleanField(
|
||||
@ -935,8 +948,8 @@ class SithFile(models.Model):
|
||||
def copy_rights(self):
|
||||
"""Copy, if possible, the rights of the parent folder"""
|
||||
if self.parent is not None:
|
||||
self.edit_groups = self.parent.edit_groups.all()
|
||||
self.view_groups = self.parent.view_groups.all()
|
||||
self.edit_groups.set(self.parent.edit_groups.all())
|
||||
self.view_groups.set(self.parent.view_groups.all())
|
||||
self.save()
|
||||
|
||||
def move_to(self, parent):
|
||||
@ -1133,6 +1146,7 @@ class Page(models.Model):
|
||||
related_name="owned_page",
|
||||
verbose_name=_("owner group"),
|
||||
default=get_default_owner_group,
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
edit_groups = models.ManyToManyField(
|
||||
Group, related_name="editable_page", verbose_name=_("edit group"), blank=True
|
||||
@ -1147,6 +1161,7 @@ class Page(models.Model):
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
lock_timeout = models.DateTimeField(
|
||||
_("lock_timeout"), null=True, blank=True, default=None
|
||||
@ -1156,7 +1171,6 @@ class Page(models.Model):
|
||||
unique_together = ("name", "parent")
|
||||
permissions = (
|
||||
("change_prop_page", "Can change the page's properties (groups, ...)"),
|
||||
("view_page", "Can view the page"),
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
@ -1347,8 +1361,8 @@ class PageRev(models.Model):
|
||||
title = models.CharField(_("page title"), max_length=255, blank=True)
|
||||
content = models.TextField(_("page content"), blank=True)
|
||||
date = models.DateTimeField(_("date"), auto_now=True)
|
||||
author = models.ForeignKey(User, related_name="page_rev")
|
||||
page = models.ForeignKey(Page, related_name="revisions")
|
||||
author = models.ForeignKey(User, related_name="page_rev", on_delete=models.CASCADE)
|
||||
page = models.ForeignKey(Page, related_name="revisions", on_delete=models.CASCADE)
|
||||
|
||||
class Meta:
|
||||
ordering = ["date"]
|
||||
@ -1386,7 +1400,9 @@ class PageRev(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)
|
||||
param = models.CharField(_("param"), max_length=128, default="")
|
||||
type = models.CharField(
|
||||
@ -1422,7 +1438,7 @@ class Notification(models.Model):
|
||||
class Gift(models.Model):
|
||||
label = models.CharField(_("label"), max_length=255)
|
||||
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):
|
||||
return "%s - %s" % (self.translated_label, self.date.strftime("%d %b %Y"))
|
||||
|
@ -39,7 +39,7 @@
|
||||
</div>
|
||||
|
||||
<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;">
|
||||
<a href="{{ url('core:index') }}"></a>
|
||||
</div>
|
||||
|
@ -11,7 +11,7 @@
|
||||
{% endif %}
|
||||
|
||||
{% if next %}
|
||||
{% if user.is_authenticated() %}
|
||||
{% if user.is_authenticated %}
|
||||
<p>{% trans %}Your account doesn't have access to this page. To proceed,
|
||||
please login with an account that has access.{% endtrans %}</p>
|
||||
{% else %}
|
||||
|
@ -25,7 +25,7 @@
|
||||
import os
|
||||
|
||||
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 core.models import User, Group, Page
|
||||
|
140
core/urls.py
140
core/urls.py
@ -23,189 +23,209 @@
|
||||
#
|
||||
#
|
||||
|
||||
from django.conf.urls import url
|
||||
from django.urls import re_path
|
||||
|
||||
from core.views import *
|
||||
|
||||
urlpatterns = [
|
||||
url(r"^$", index, name="index"),
|
||||
url(r"^to_markdown$", ToMarkdownView.as_view(), name="to_markdown"),
|
||||
url(r"^notifications$", NotificationList.as_view(), name="notification_list"),
|
||||
url(r"^notification/(?P<notif_id>[0-9]+)$", notification, name="notification"),
|
||||
re_path(r"^$", index, name="index"),
|
||||
re_path(r"^to_markdown$", ToMarkdownView.as_view(), name="to_markdown"),
|
||||
re_path(r"^notifications$", NotificationList.as_view(), name="notification_list"),
|
||||
re_path(r"^notification/(?P<notif_id>[0-9]+)$", notification, name="notification"),
|
||||
# Search
|
||||
url(r"^search/$", search_view, name="search"),
|
||||
url(r"^search_json/$", search_json, name="search_json"),
|
||||
url(r"^search_user/$", search_user_json, name="search_user"),
|
||||
re_path(r"^search/$", search_view, name="search"),
|
||||
re_path(r"^search_json/$", search_json, name="search_json"),
|
||||
re_path(r"^search_user/$", search_user_json, name="search_user"),
|
||||
# Login and co
|
||||
url(r"^login/$", login, name="login"),
|
||||
url(r"^logout/$", logout, name="logout"),
|
||||
url(r"^password_change/$", password_change, name="password_change"),
|
||||
url(
|
||||
re_path(r"^login/$", SithLoginView.as_view(), name="login"),
|
||||
re_path(r"^logout/$", logout, name="logout"),
|
||||
re_path(
|
||||
r"^password_change/$", SithPasswordChangeView.as_view(), name="password_change"
|
||||
),
|
||||
re_path(
|
||||
r"^password_change/(?P<user_id>[0-9]+)$",
|
||||
password_root_change,
|
||||
name="password_root_change",
|
||||
),
|
||||
url(r"^password_change/done$", password_change_done, name="password_change_done"),
|
||||
url(r"^password_reset/$", password_reset, name="password_reset"),
|
||||
url(r"^password_reset/done$", password_reset_done, name="password_reset_done"),
|
||||
url(
|
||||
re_path(
|
||||
r"^password_change/done$",
|
||||
SithPasswordChangeDoneView.as_view(),
|
||||
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})/$",
|
||||
password_reset_confirm,
|
||||
SithPasswordResetConfirmView.as_view(),
|
||||
name="password_reset_confirm",
|
||||
),
|
||||
url(r"^reset/done/$", password_reset_complete, name="password_reset_complete"),
|
||||
url(r"^register$", register, name="register"),
|
||||
re_path(
|
||||
r"^reset/done/$",
|
||||
SithPasswordResetCompleteView.as_view(),
|
||||
name="password_reset_complete",
|
||||
),
|
||||
re_path(r"^register$", register, name="register"),
|
||||
# Group handling
|
||||
url(r"^group/$", GroupListView.as_view(), name="group_list"),
|
||||
url(r"^group/new$", GroupCreateView.as_view(), name="group_new"),
|
||||
url(r"^group/(?P<group_id>[0-9]+)/$", GroupEditView.as_view(), name="group_edit"),
|
||||
url(
|
||||
re_path(r"^group/$", GroupListView.as_view(), name="group_list"),
|
||||
re_path(r"^group/new$", GroupCreateView.as_view(), name="group_new"),
|
||||
re_path(
|
||||
r"^group/(?P<group_id>[0-9]+)/$", GroupEditView.as_view(), name="group_edit"
|
||||
),
|
||||
re_path(
|
||||
r"^group/(?P<group_id>[0-9]+)/delete$",
|
||||
GroupDeleteView.as_view(),
|
||||
name="group_delete",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^group/(?P<group_id>[0-9]+)/detail$",
|
||||
GroupTemplateView.as_view(),
|
||||
name="group_detail",
|
||||
),
|
||||
# User views
|
||||
url(r"^user/$", UserListView.as_view(), name="user_list"),
|
||||
url(
|
||||
re_path(r"^user/$", UserListView.as_view(), name="user_list"),
|
||||
re_path(
|
||||
r"^user/(?P<user_id>[0-9]+)/mini$",
|
||||
UserMiniView.as_view(),
|
||||
name="user_profile_mini",
|
||||
),
|
||||
url(r"^user/(?P<user_id>[0-9]+)/$", UserView.as_view(), name="user_profile"),
|
||||
url(
|
||||
re_path(r"^user/(?P<user_id>[0-9]+)/$", UserView.as_view(), name="user_profile"),
|
||||
re_path(
|
||||
r"^user/(?P<user_id>[0-9]+)/pictures$",
|
||||
UserPicturesView.as_view(),
|
||||
name="user_pictures",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^user/(?P<user_id>[0-9]+)/godfathers$",
|
||||
UserGodfathersView.as_view(),
|
||||
name="user_godfathers",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^user/(?P<user_id>[0-9]+)/godfathers/tree$",
|
||||
UserGodfathersTreeView.as_view(),
|
||||
name="user_godfathers_tree",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^user/(?P<user_id>[0-9]+)/godfathers/tree/pict$",
|
||||
UserGodfathersTreePictureView.as_view(),
|
||||
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$",
|
||||
DeleteUserGodfathers,
|
||||
name="user_godfathers_delete",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^user/(?P<user_id>[0-9]+)/edit$",
|
||||
UserUpdateProfileView.as_view(),
|
||||
name="user_edit",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^user/(?P<user_id>[0-9]+)/profile_upload$",
|
||||
UserUploadProfilePictView.as_view(),
|
||||
name="user_profile_upload",
|
||||
),
|
||||
url(r"^user/(?P<user_id>[0-9]+)/clubs$", UserClubView.as_view(), name="user_clubs"),
|
||||
url(
|
||||
re_path(
|
||||
r"^user/(?P<user_id>[0-9]+)/clubs$", UserClubView.as_view(), name="user_clubs"
|
||||
),
|
||||
re_path(
|
||||
r"^user/(?P<user_id>[0-9]+)/prefs$",
|
||||
UserPreferencesView.as_view(),
|
||||
name="user_prefs",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^user/(?P<user_id>[0-9]+)/groups$",
|
||||
UserUpdateGroupView.as_view(),
|
||||
name="user_groups",
|
||||
),
|
||||
url(r"^user/tools/$", UserToolsView.as_view(), name="user_tools"),
|
||||
url(
|
||||
re_path(r"^user/tools/$", UserToolsView.as_view(), name="user_tools"),
|
||||
re_path(
|
||||
r"^user/(?P<user_id>[0-9]+)/account$",
|
||||
UserAccountView.as_view(),
|
||||
name="user_account",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^user/(?P<user_id>[0-9]+)/account/(?P<year>[0-9]+)/(?P<month>[0-9]+)$",
|
||||
UserAccountDetailView.as_view(),
|
||||
name="user_account_detail",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
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$",
|
||||
GiftCreateView.as_view(),
|
||||
name="user_gift_create",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^user/(?P<user_id>[0-9]+)/gift/delete/(?P<gift_id>[0-9]+)/$",
|
||||
GiftDeleteView.as_view(),
|
||||
name="user_gift_delete",
|
||||
),
|
||||
# File views
|
||||
# url(r'^file/add/(?P<popup>popup)?$', FileCreateView.as_view(), name='file_new'),
|
||||
url(r"^file/(?P<popup>popup)?$", FileListView.as_view(), name="file_list"),
|
||||
url(
|
||||
# re_path(r'^file/add/(?P<popup>popup)?$', FileCreateView.as_view(), name='file_new'),
|
||||
re_path(r"^file/(?P<popup>popup)?$", FileListView.as_view(), name="file_list"),
|
||||
re_path(
|
||||
r"^file/(?P<file_id>[0-9]+)/(?P<popup>popup)?$",
|
||||
FileView.as_view(),
|
||||
name="file_detail",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^file/(?P<file_id>[0-9]+)/edit/(?P<popup>popup)?$",
|
||||
FileEditView.as_view(),
|
||||
name="file_edit",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^file/(?P<file_id>[0-9]+)/prop/(?P<popup>popup)?$",
|
||||
FileEditPropView.as_view(),
|
||||
name="file_prop",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^file/(?P<file_id>[0-9]+)/delete/(?P<popup>popup)?$",
|
||||
FileDeleteView.as_view(),
|
||||
name="file_delete",
|
||||
),
|
||||
url(r"^file/moderation$", FileModerationView.as_view(), name="file_moderation"),
|
||||
url(
|
||||
re_path(r"^file/moderation$", FileModerationView.as_view(), name="file_moderation"),
|
||||
re_path(
|
||||
r"^file/(?P<file_id>[0-9]+)/moderate$",
|
||||
FileModerateView.as_view(),
|
||||
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
|
||||
url(r"^page/$", PageListView.as_view(), name="page_list"),
|
||||
url(r"^page/create$", PageCreateView.as_view(), name="page_new"),
|
||||
url(
|
||||
re_path(r"^page/$", PageListView.as_view(), name="page_list"),
|
||||
re_path(r"^page/create$", PageCreateView.as_view(), name="page_new"),
|
||||
re_path(
|
||||
r"^page/(?P<page_id>[0-9]*)/delete$",
|
||||
PageDeleteView.as_view(),
|
||||
name="page_delete",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^page/(?P<page_name>([/a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9])+)/edit$",
|
||||
PageEditView.as_view(),
|
||||
name="page_edit",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^page/(?P<page_name>([/a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9])+)/prop$",
|
||||
PagePropView.as_view(),
|
||||
name="page_prop",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^page/(?P<page_name>([/a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9])+)/hist$",
|
||||
PageHistView.as_view(),
|
||||
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]+)/",
|
||||
PageRevView.as_view(),
|
||||
name="page_rev",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^page/(?P<page_name>([/a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9])+)/$",
|
||||
PageView.as_view(),
|
||||
name="page",
|
||||
|
@ -48,7 +48,7 @@ from core.models import Group
|
||||
from core.views.forms import LoginForm
|
||||
|
||||
|
||||
def forbidden(request):
|
||||
def forbidden(request, exception):
|
||||
try:
|
||||
return HttpResponseForbidden(
|
||||
render(
|
||||
@ -71,7 +71,7 @@ def forbidden(request):
|
||||
)
|
||||
|
||||
|
||||
def not_found(request):
|
||||
def not_found(request, exception):
|
||||
return HttpResponseNotFound(render(request, "core/404.jinja"))
|
||||
|
||||
|
||||
@ -150,7 +150,7 @@ class CanCreateMixin(View):
|
||||
|
||||
def dispatch(self, 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
|
||||
return res
|
||||
|
||||
|
@ -32,7 +32,7 @@ from django.conf import settings
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.http import HttpResponse
|
||||
from wsgiref.util import FileWrapper
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.urls import reverse
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django import forms
|
||||
|
||||
@ -109,7 +109,7 @@ class AddFilesForm(forms.Form):
|
||||
owner=owner,
|
||||
is_folder=False,
|
||||
mime_type=f.content_type,
|
||||
size=f._size,
|
||||
size=f.size,
|
||||
)
|
||||
try:
|
||||
new_file.clean()
|
||||
@ -289,7 +289,7 @@ class FileView(CanViewMixin, DetailView, FormMixin):
|
||||
self.form = self.get_form() # The form handle only the file upload
|
||||
files = request.FILES.getlist("file_field")
|
||||
if (
|
||||
request.user.is_authenticated()
|
||||
request.user.is_authenticated
|
||||
and request.user.can_edit(self.object)
|
||||
and self.form.is_valid()
|
||||
):
|
||||
|
@ -27,7 +27,7 @@ from django import forms
|
||||
from django.conf import settings
|
||||
from django.db import transaction
|
||||
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.forms import (
|
||||
CheckboxSelectMultiple,
|
||||
@ -56,39 +56,39 @@ from PIL import Image
|
||||
|
||||
|
||||
class SelectSingle(Select):
|
||||
def render(self, name, value, attrs=None):
|
||||
def render(self, name, value, attrs=None, renderer=None):
|
||||
if attrs:
|
||||
attrs["class"] = "select_single"
|
||||
else:
|
||||
attrs = {"class": "select_single"}
|
||||
return super(SelectSingle, self).render(name, value, attrs)
|
||||
return super(SelectSingle, self).render(name, value, attrs, renderer)
|
||||
|
||||
|
||||
class SelectMultiple(Select):
|
||||
def render(self, name, value, attrs=None):
|
||||
def render(self, name, value, attrs=None, renderer=None):
|
||||
if attrs:
|
||||
attrs["class"] = "select_multiple"
|
||||
else:
|
||||
attrs = {"class": "select_multiple"}
|
||||
return super(SelectMultiple, self).render(name, value, attrs)
|
||||
return super(SelectMultiple, self).render(name, value, attrs, renderer)
|
||||
|
||||
|
||||
class SelectDateTime(DateTimeInput):
|
||||
def render(self, name, value, attrs=None):
|
||||
def render(self, name, value, attrs=None, renderer=None):
|
||||
if attrs:
|
||||
attrs["class"] = "select_datetime"
|
||||
else:
|
||||
attrs = {"class": "select_datetime"}
|
||||
return super(SelectDateTime, self).render(name, value, attrs)
|
||||
return super(SelectDateTime, self).render(name, value, attrs, renderer)
|
||||
|
||||
|
||||
class SelectDate(DateInput):
|
||||
def render(self, name, value, attrs=None):
|
||||
def render(self, name, value, attrs=None, renderer=None):
|
||||
if attrs:
|
||||
attrs["class"] = "select_date"
|
||||
else:
|
||||
attrs = {"class": "select_date"}
|
||||
return super(SelectDate, self).render(name, value, attrs)
|
||||
return super(SelectDate, self).render(name, value, attrs, renderer)
|
||||
|
||||
|
||||
class MarkdownInput(Textarea):
|
||||
@ -127,7 +127,7 @@ class MarkdownInput(Textarea):
|
||||
|
||||
|
||||
class SelectFile(TextInput):
|
||||
def render(self, name, value, attrs=None):
|
||||
def render(self, name, value, attrs=None, renderer=None):
|
||||
if attrs:
|
||||
attrs["class"] = "select_file"
|
||||
else:
|
||||
@ -135,7 +135,7 @@ class SelectFile(TextInput):
|
||||
output = (
|
||||
'%(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"),
|
||||
"name": name,
|
||||
}
|
||||
@ -151,7 +151,7 @@ class SelectFile(TextInput):
|
||||
|
||||
|
||||
class SelectUser(TextInput):
|
||||
def render(self, name, value, attrs=None):
|
||||
def render(self, name, value, attrs=None, renderer=None):
|
||||
if attrs:
|
||||
attrs["class"] = "select_user"
|
||||
else:
|
||||
@ -159,7 +159,7 @@ class SelectUser(TextInput):
|
||||
output = (
|
||||
'%(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"),
|
||||
"name": name,
|
||||
}
|
||||
@ -302,7 +302,7 @@ class UserProfileForm(forms.ModelForm):
|
||||
owner=self.instance,
|
||||
is_folder=False,
|
||||
mime_type=f.content_type,
|
||||
size=f._size,
|
||||
size=f.size,
|
||||
moderator=self.instance,
|
||||
is_moderated=True,
|
||||
)
|
||||
|
@ -29,7 +29,7 @@
|
||||
from django.views.generic.edit import UpdateView, CreateView, DeleteView
|
||||
from django.views.generic import ListView
|
||||
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.utils.translation import ugettext_lazy as _
|
||||
from django import forms
|
||||
|
@ -23,7 +23,7 @@
|
||||
#
|
||||
|
||||
# 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.edit import UpdateView, CreateView, DeleteView
|
||||
from django.forms.models import modelform_factory
|
||||
|
@ -26,8 +26,9 @@
|
||||
# This file contains all the views that concern the user model
|
||||
from django.shortcuts import render, redirect, get_object_or_404
|
||||
from django.contrib.auth import views
|
||||
from django.contrib.auth.forms import PasswordChangeForm
|
||||
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.http import Http404, HttpResponse
|
||||
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 import CheckboxSelectMultiple
|
||||
from django.core.urlresolvers import reverse_lazy
|
||||
from django.urls import reverse_lazy
|
||||
from django.template.response import TemplateResponse
|
||||
from django.conf import settings
|
||||
from django.views.generic.dates import YearMixin, MonthMixin
|
||||
@ -69,15 +70,31 @@ from counter.views import StudentCardForm
|
||||
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(
|
||||
request, template_name="core/login.jinja", authentication_form=LoginForm
|
||||
)
|
||||
Allows a user to change its password
|
||||
"""
|
||||
|
||||
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):
|
||||
@ -87,26 +104,6 @@ def logout(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):
|
||||
"""
|
||||
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
|
||||
"""
|
||||
return views.password_reset(
|
||||
request,
|
||||
template_name="core/password_reset.jinja",
|
||||
email_template_name="core/password_reset_email.jinja",
|
||||
post_reset_redirect="core:password_reset_done",
|
||||
)
|
||||
|
||||
template_name = "core/password_reset.jinja"
|
||||
email_template_name = "core/password_reset_email.jinja"
|
||||
success_url = reverse_lazy("core:password_reset_done")
|
||||
|
||||
|
||||
def password_reset_done(request):
|
||||
class SithPasswordResetDoneView(views.PasswordResetDoneView):
|
||||
"""
|
||||
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,
|
||||
uidb64=uidb64,
|
||||
token=token,
|
||||
post_reset_redirect="core:password_reset_complete",
|
||||
template_name="core/password_reset_confirm.jinja",
|
||||
)
|
||||
|
||||
template_name = "core/password_reset_confirm.jinja"
|
||||
success_url = reverse_lazy("core:password_reset_complete")
|
||||
|
||||
|
||||
def password_reset_complete(request):
|
||||
class SithPasswordResetCompleteView(views.PasswordResetCompleteView):
|
||||
"""
|
||||
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):
|
||||
@ -641,7 +630,7 @@ class UserUploadProfilePictView(CanEditMixin, DetailView):
|
||||
owner=self.object,
|
||||
is_folder=False,
|
||||
mime_type=f.content_type,
|
||||
size=f._size,
|
||||
size=f.size,
|
||||
)
|
||||
new_file.file.name = name
|
||||
new_file.save()
|
||||
@ -689,7 +678,7 @@ class UserUpdateProfileView(UserTabsMixin, CanEditMixin, UpdateView):
|
||||
files = request.FILES.items()
|
||||
self.form.process(files)
|
||||
if (
|
||||
request.user.is_authenticated()
|
||||
request.user.is_authenticated
|
||||
and request.user.can_edit(self.object)
|
||||
and self.form.is_valid()
|
||||
):
|
||||
|
@ -5,6 +5,7 @@ from django.db import migrations, models
|
||||
import accounting.models
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
@ -42,7 +43,14 @@ class Migration(migrations.Migration):
|
||||
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",
|
||||
models.ManyToManyField(
|
||||
@ -58,7 +66,10 @@ class Migration(migrations.Migration):
|
||||
(
|
||||
"user",
|
||||
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",
|
||||
models.ForeignKey(
|
||||
to="counter.Counter", related_name="permanencies"
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
to="counter.Counter",
|
||||
related_name="permanencies",
|
||||
),
|
||||
),
|
||||
(
|
||||
"user",
|
||||
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",
|
||||
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",
|
||||
models.ForeignKey(to="counter.Counter", related_name="refillings"),
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
to="counter.Counter",
|
||||
related_name="refillings",
|
||||
),
|
||||
),
|
||||
(
|
||||
"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",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
related_name="refillings_as_operator",
|
||||
),
|
||||
|
@ -4,6 +4,7 @@ from __future__ import unicode_literals
|
||||
from django.db import migrations, models
|
||||
from django.conf import settings
|
||||
import accounting.models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
@ -35,6 +36,7 @@ class Migration(migrations.Migration):
|
||||
(
|
||||
"counter",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
to="counter.Counter",
|
||||
related_name="cash_summaries",
|
||||
verbose_name="counter",
|
||||
@ -43,6 +45,7 @@ class Migration(migrations.Migration):
|
||||
(
|
||||
"user",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
related_name="cash_summaries",
|
||||
verbose_name="user",
|
||||
@ -74,6 +77,7 @@ class Migration(migrations.Migration):
|
||||
(
|
||||
"cash_summary",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
to="counter.CashRegisterSummary",
|
||||
related_name="items",
|
||||
verbose_name="cash summary",
|
||||
@ -86,6 +90,7 @@ class Migration(migrations.Migration):
|
||||
model_name="permanency",
|
||||
name="counter",
|
||||
field=models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
to="counter.Counter",
|
||||
related_name="permanencies",
|
||||
verbose_name="counter",
|
||||
@ -95,6 +100,7 @@ class Migration(migrations.Migration):
|
||||
model_name="permanency",
|
||||
name="user",
|
||||
field=models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
related_name="permanencies",
|
||||
verbose_name="user",
|
||||
|
@ -2,6 +2,7 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
@ -13,7 +14,10 @@ class Migration(migrations.Migration):
|
||||
model_name="counter",
|
||||
name="club",
|
||||
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(
|
||||
|
@ -2,6 +2,7 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
@ -32,6 +33,7 @@ class Migration(migrations.Migration):
|
||||
(
|
||||
"product",
|
||||
models.OneToOneField(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
verbose_name="product",
|
||||
related_name="eticket",
|
||||
to="counter.Product",
|
||||
|
@ -26,7 +26,7 @@ from django.db import models
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils import timezone
|
||||
from django.conf import settings
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.urls import reverse
|
||||
from django.core.validators import MinLengthValidator
|
||||
from django.forms import ValidationError
|
||||
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
|
||||
"""
|
||||
|
||||
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)
|
||||
amount = CurrencyField(_("amount"))
|
||||
recorded_products = models.IntegerField(_("recorded product"), default=0)
|
||||
@ -163,7 +163,9 @@ class Product(models.Model):
|
||||
icon = models.ImageField(
|
||||
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)
|
||||
tray = models.BooleanField(_("tray price"), default=False)
|
||||
parent_product = models.ForeignKey(
|
||||
@ -209,7 +211,9 @@ class Product(models.Model):
|
||||
|
||||
class Counter(models.Model):
|
||||
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(
|
||||
Product, related_name="counters", verbose_name=_("products"), blank=True
|
||||
)
|
||||
@ -344,12 +348,19 @@ class Refilling(models.Model):
|
||||
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"))
|
||||
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"))
|
||||
payment_method = models.CharField(
|
||||
_("payment method"),
|
||||
@ -584,9 +595,17 @@ class Permanency(models.Model):
|
||||
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, related_name="permanencies", verbose_name=_("counter")
|
||||
Counter,
|
||||
related_name="permanencies",
|
||||
verbose_name=_("counter"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
start = models.DateTimeField(_("start date"))
|
||||
end = models.DateTimeField(_("end date"), null=True, db_index=True)
|
||||
@ -607,10 +626,16 @@ class Permanency(models.Model):
|
||||
|
||||
class CashRegisterSummary(models.Model):
|
||||
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, related_name="cash_summaries", verbose_name=_("counter")
|
||||
Counter,
|
||||
related_name="cash_summaries",
|
||||
verbose_name=_("counter"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
date = models.DateTimeField(_("date"))
|
||||
comment = models.TextField(_("comment"), null=True, blank=True)
|
||||
@ -683,7 +708,10 @@ class CashRegisterSummary(models.Model):
|
||||
|
||||
class CashRegisterSummaryItem(models.Model):
|
||||
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"))
|
||||
quantity = models.IntegerField(_("quantity"), default=0)
|
||||
@ -699,7 +727,10 @@ class Eticket(models.Model):
|
||||
"""
|
||||
|
||||
product = models.OneToOneField(
|
||||
Product, related_name="eticket", verbose_name=_("product")
|
||||
Product,
|
||||
related_name="eticket",
|
||||
verbose_name=_("product"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
banner = models.ImageField(
|
||||
upload_to="etickets", null=True, blank=True, verbose_name=_("banner")
|
||||
@ -772,4 +803,5 @@ class StudentCard(models.Model):
|
||||
verbose_name=_("student cards"),
|
||||
null=False,
|
||||
blank=False,
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
@ -25,7 +25,7 @@
|
||||
import re
|
||||
|
||||
from django.test import TestCase
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.urls import reverse
|
||||
from django.core.management import call_command
|
||||
|
||||
from core.models import User
|
||||
|
@ -22,119 +22,119 @@
|
||||
#
|
||||
#
|
||||
|
||||
from django.conf.urls import url
|
||||
from django.urls import re_path
|
||||
|
||||
from counter.views import *
|
||||
|
||||
urlpatterns = [
|
||||
url(r"^(?P<counter_id>[0-9]+)$", CounterMain.as_view(), name="details"),
|
||||
url(
|
||||
re_path(r"^(?P<counter_id>[0-9]+)$", CounterMain.as_view(), name="details"),
|
||||
re_path(
|
||||
r"^(?P<counter_id>[0-9]+)/click/(?P<user_id>[0-9]+)$",
|
||||
CounterClick.as_view(),
|
||||
name="click",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^(?P<counter_id>[0-9]+)/last_ops$",
|
||||
CounterLastOperationsView.as_view(),
|
||||
name="last_ops",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^(?P<counter_id>[0-9]+)/cash_summary$",
|
||||
CounterCashSummaryView.as_view(),
|
||||
name="cash_summary",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^(?P<counter_id>[0-9]+)/activity$",
|
||||
CounterActivityView.as_view(),
|
||||
name="activity",
|
||||
),
|
||||
url(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"),
|
||||
url(r"^(?P<counter_id>[0-9]+)/logout$", CounterLogout.as_view(), name="logout"),
|
||||
url(
|
||||
re_path(r"^(?P<counter_id>[0-9]+)/stats$", CounterStatView.as_view(), name="stats"),
|
||||
re_path(r"^(?P<counter_id>[0-9]+)/login$", CounterLogin.as_view(), name="login"),
|
||||
re_path(r"^(?P<counter_id>[0-9]+)/logout$", CounterLogout.as_view(), name="logout"),
|
||||
re_path(
|
||||
r"^eticket/(?P<selling_id>[0-9]+)/pdf$",
|
||||
EticketPDFView.as_view(),
|
||||
name="eticket_pdf",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^customer/(?P<customer_id>[0-9]+)/card/add$",
|
||||
StudentCardFormView.as_view(),
|
||||
name="add_student_card",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^customer/(?P<customer_id>[0-9]+)/card/delete/(?P<card_id>[0-9]+)/$",
|
||||
StudentCardDeleteView.as_view(),
|
||||
name="delete_student_card",
|
||||
),
|
||||
url(r"^admin/(?P<counter_id>[0-9]+)$", CounterEditView.as_view(), name="admin"),
|
||||
url(
|
||||
re_path(r"^admin/(?P<counter_id>[0-9]+)$", CounterEditView.as_view(), name="admin"),
|
||||
re_path(
|
||||
r"^admin/(?P<counter_id>[0-9]+)/prop$",
|
||||
CounterEditPropView.as_view(),
|
||||
name="prop_admin",
|
||||
),
|
||||
url(r"^admin$", CounterListView.as_view(), name="admin_list"),
|
||||
url(r"^admin/new$", CounterCreateView.as_view(), name="new"),
|
||||
url(
|
||||
re_path(r"^admin$", CounterListView.as_view(), name="admin_list"),
|
||||
re_path(r"^admin/new$", CounterCreateView.as_view(), name="new"),
|
||||
re_path(
|
||||
r"^admin/delete/(?P<counter_id>[0-9]+)$",
|
||||
CounterDeleteView.as_view(),
|
||||
name="delete",
|
||||
),
|
||||
url(r"^admin/invoices_call$", InvoiceCallView.as_view(), name="invoices_call"),
|
||||
url(
|
||||
re_path(r"^admin/invoices_call$", InvoiceCallView.as_view(), name="invoices_call"),
|
||||
re_path(
|
||||
r"^admin/cash_summary/list$",
|
||||
CashSummaryListView.as_view(),
|
||||
name="cash_summary_list",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^admin/cash_summary/(?P<cashsummary_id>[0-9]+)$",
|
||||
CashSummaryEditView.as_view(),
|
||||
name="cash_summary_edit",
|
||||
),
|
||||
url(r"^admin/product/list$", ProductListView.as_view(), name="product_list"),
|
||||
url(
|
||||
re_path(r"^admin/product/list$", ProductListView.as_view(), name="product_list"),
|
||||
re_path(
|
||||
r"^admin/product/list_archived$",
|
||||
ProductArchivedListView.as_view(),
|
||||
name="product_list_archived",
|
||||
),
|
||||
url(r"^admin/product/create$", ProductCreateView.as_view(), name="new_product"),
|
||||
url(
|
||||
re_path(r"^admin/product/create$", ProductCreateView.as_view(), name="new_product"),
|
||||
re_path(
|
||||
r"^admin/product/(?P<product_id>[0-9]+)$",
|
||||
ProductEditView.as_view(),
|
||||
name="product_edit",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^admin/producttype/list$",
|
||||
ProductTypeListView.as_view(),
|
||||
name="producttype_list",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^admin/producttype/create$",
|
||||
ProductTypeCreateView.as_view(),
|
||||
name="new_producttype",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^admin/producttype/(?P<type_id>[0-9]+)$",
|
||||
ProductTypeEditView.as_view(),
|
||||
name="producttype_edit",
|
||||
),
|
||||
url(r"^admin/eticket/list$", EticketListView.as_view(), name="eticket_list"),
|
||||
url(r"^admin/eticket/new$", EticketCreateView.as_view(), name="new_eticket"),
|
||||
url(
|
||||
re_path(r"^admin/eticket/list$", EticketListView.as_view(), name="eticket_list"),
|
||||
re_path(r"^admin/eticket/new$", EticketCreateView.as_view(), name="new_eticket"),
|
||||
re_path(
|
||||
r"^admin/eticket/(?P<eticket_id>[0-9]+)$",
|
||||
EticketEditView.as_view(),
|
||||
name="edit_eticket",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^admin/selling/(?P<selling_id>[0-9]+)/delete$",
|
||||
SellingDeleteView.as_view(),
|
||||
name="selling_delete",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^admin/refilling/(?P<refilling_id>[0-9]+)/delete$",
|
||||
RefillingDeleteView.as_view(),
|
||||
name="refilling_delete",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^admin/(?P<counter_id>[0-9]+)/refillings$",
|
||||
CounterRefillingListView.as_view(),
|
||||
name="refilling_list",
|
||||
|
@ -37,7 +37,7 @@ from django.views.generic.edit import (
|
||||
)
|
||||
from django.forms.models import modelform_factory
|
||||
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.utils import timezone
|
||||
from django import forms
|
||||
@ -323,7 +323,7 @@ class CounterMain(
|
||||
)
|
||||
if self.object.type == "BAR":
|
||||
kwargs["barmen"] = self.object.get_barmen_list()
|
||||
elif self.request.user.is_authenticated():
|
||||
elif self.request.user.is_authenticated:
|
||||
kwargs["barmen"] = [self.request.user]
|
||||
if "last_basket" in self.request.session.keys():
|
||||
kwargs["last_basket"] = self.request.session.pop("last_basket")
|
||||
@ -372,7 +372,7 @@ class CounterClick(CounterTabsMixin, CanViewMixin, DetailView):
|
||||
):
|
||||
raise PermissionDenied
|
||||
else:
|
||||
if not request.user.is_authenticated():
|
||||
if not request.user.is_authenticated:
|
||||
raise PermissionDenied
|
||||
return super(CounterClick, self).dispatch(request, *args, **kwargs)
|
||||
|
||||
@ -387,7 +387,7 @@ class CounterClick(CounterTabsMixin, CanViewMixin, DetailView):
|
||||
request.session["no_age"] = False
|
||||
self.refill_form = None
|
||||
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
|
||||
): # Check that at least one barman is logged in
|
||||
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 """
|
||||
self.object = self.get_object()
|
||||
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
|
||||
): # Check that at least one barman is logged in
|
||||
return self.cancel(request)
|
||||
@ -1554,13 +1554,13 @@ class CashSummaryEditView(CounterAdminTabsMixin, CounterAdminMixin, UpdateView):
|
||||
|
||||
class CashSummaryFormBase(forms.Form):
|
||||
begin_date = forms.DateTimeField(
|
||||
["%Y-%m-%d %H:%M:%S"],
|
||||
input_formats=["%Y-%m-%d %H:%M:%S"],
|
||||
label=_("Begin date"),
|
||||
required=False,
|
||||
widget=SelectDateTime,
|
||||
)
|
||||
end_date = forms.DateTimeField(
|
||||
["%Y-%m-%d %H:%M:%S"],
|
||||
input_formats=["%Y-%m-%d %H:%M:%S"],
|
||||
label=_("End date"),
|
||||
required=False,
|
||||
widget=SelectDateTime,
|
||||
|
@ -4,6 +4,7 @@ from __future__ import unicode_literals
|
||||
from django.db import migrations, models
|
||||
import accounting.models
|
||||
from django.conf import settings
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
@ -27,6 +28,7 @@ class Migration(migrations.Migration):
|
||||
(
|
||||
"user",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
verbose_name="user",
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
related_name="baskets",
|
||||
@ -62,7 +64,10 @@ class Migration(migrations.Migration):
|
||||
(
|
||||
"basket",
|
||||
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",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
verbose_name="user",
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
related_name="invoices",
|
||||
@ -123,6 +129,7 @@ class Migration(migrations.Migration):
|
||||
(
|
||||
"invoice",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
verbose_name="invoice",
|
||||
to="eboutic.Invoice",
|
||||
related_name="items",
|
||||
|
@ -37,7 +37,11 @@ class Basket(models.Model):
|
||||
"""
|
||||
|
||||
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)
|
||||
|
||||
@ -80,7 +84,11 @@ class Invoice(models.Model):
|
||||
"""
|
||||
|
||||
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)
|
||||
validated = models.BooleanField(_("validated"), default=False)
|
||||
@ -158,10 +166,15 @@ class AbstractBaseItem(models.Model):
|
||||
|
||||
|
||||
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):
|
||||
invoice = models.ForeignKey(
|
||||
Invoice, related_name="items", verbose_name=_("invoice")
|
||||
Invoice,
|
||||
related_name="items",
|
||||
verbose_name=_("invoice"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
@ -29,7 +29,7 @@ import urllib
|
||||
from OpenSSL import crypto
|
||||
|
||||
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.conf import settings
|
||||
|
||||
|
@ -22,16 +22,16 @@
|
||||
#
|
||||
#
|
||||
|
||||
from django.conf.urls import url
|
||||
from django.urls import re_path
|
||||
|
||||
from eboutic.views import *
|
||||
|
||||
urlpatterns = [
|
||||
# Subscription views
|
||||
url(r"^$", EbouticMain.as_view(), name="main"),
|
||||
url(r"^command$", EbouticCommand.as_view(), name="command"),
|
||||
url(r"^pay$", EbouticPayWithSith.as_view(), name="pay_with_sith"),
|
||||
url(
|
||||
re_path(r"^$", EbouticMain.as_view(), name="main"),
|
||||
re_path(r"^command$", EbouticCommand.as_view(), name="command"),
|
||||
re_path(r"^pay$", EbouticPayWithSith.as_view(), name="pay_with_sith"),
|
||||
re_path(
|
||||
r"^et_autoanswer$",
|
||||
EtransactionAutoAnswer.as_view(),
|
||||
name="etransation_autoanswer",
|
||||
|
@ -28,7 +28,7 @@ import hmac
|
||||
import base64
|
||||
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.http import HttpResponse, HttpResponseRedirect
|
||||
from django.core.exceptions import SuspiciousOperation
|
||||
@ -56,7 +56,7 @@ class EbouticMain(TemplateView):
|
||||
request.session.modified = True
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
if not request.user.is_authenticated():
|
||||
if not request.user.is_authenticated:
|
||||
return HttpResponseRedirect(
|
||||
reverse_lazy("core:login", args=self.args, kwargs=kwargs)
|
||||
+ "?next="
|
||||
@ -67,7 +67,7 @@ class EbouticMain(TemplateView):
|
||||
return super(EbouticMain, self).get(request, *args, **kwargs)
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
if not request.user.is_authenticated():
|
||||
if not request.user.is_authenticated:
|
||||
return HttpResponseRedirect(
|
||||
reverse_lazy("core:login", args=self.args, kwargs=kwargs)
|
||||
+ "?next="
|
||||
@ -118,7 +118,7 @@ class EbouticCommand(TemplateView):
|
||||
template_name = "eboutic/eboutic_makecommand.jinja"
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
if not request.user.is_authenticated():
|
||||
if not request.user.is_authenticated:
|
||||
return HttpResponseRedirect(
|
||||
reverse_lazy("core:login", args=self.args, kwargs=kwargs)
|
||||
+ "?next="
|
||||
@ -129,7 +129,7 @@ class EbouticCommand(TemplateView):
|
||||
)
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
if not request.user.is_authenticated():
|
||||
if not request.user.is_authenticated:
|
||||
return HttpResponseRedirect(
|
||||
reverse_lazy("core:login", args=self.args, kwargs=kwargs)
|
||||
+ "?next="
|
||||
@ -192,7 +192,7 @@ class EbouticPayWithSith(TemplateView):
|
||||
with transaction.atomic():
|
||||
if (
|
||||
"basket_id" not in request.session.keys()
|
||||
or not request.user.is_authenticated()
|
||||
or not request.user.is_authenticated
|
||||
):
|
||||
return HttpResponseRedirect(
|
||||
reverse_lazy("eboutic:main", args=self.args, kwargs=kwargs)
|
||||
|
@ -3,6 +3,7 @@ from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
from django.conf import settings
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
@ -120,6 +121,7 @@ class Migration(migrations.Migration):
|
||||
(
|
||||
"election",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
verbose_name="election",
|
||||
to="election.Election",
|
||||
related_name="election_lists",
|
||||
@ -151,6 +153,7 @@ class Migration(migrations.Migration):
|
||||
(
|
||||
"election",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
verbose_name="election",
|
||||
to="election.Election",
|
||||
related_name="roles",
|
||||
@ -181,7 +184,10 @@ class Migration(migrations.Migration):
|
||||
(
|
||||
"role",
|
||||
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",
|
||||
name="election_list",
|
||||
field=models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
verbose_name="election list",
|
||||
to="election.ElectionList",
|
||||
related_name="candidatures",
|
||||
@ -199,13 +206,17 @@ class Migration(migrations.Migration):
|
||||
model_name="candidature",
|
||||
name="role",
|
||||
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(
|
||||
model_name="candidature",
|
||||
name="user",
|
||||
field=models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
verbose_name="user",
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
related_name="candidates",
|
||||
|
18
election/migrations/0004_auto_20191006_0049.py
Normal file
18
election/migrations/0004_auto_20191006_0049.py
Normal 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"
|
||||
),
|
||||
)
|
||||
]
|
@ -111,7 +111,10 @@ class Role(OrderedModel):
|
||||
"""
|
||||
|
||||
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)
|
||||
description = models.TextField(_("description"), null=True, blank=True)
|
||||
@ -155,7 +158,10 @@ class ElectionList(models.Model):
|
||||
|
||||
title = models.CharField(_("title"), max_length=255)
|
||||
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):
|
||||
@ -175,13 +181,25 @@ class Candidature(models.Model):
|
||||
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, 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)
|
||||
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):
|
||||
@ -201,7 +219,9 @@ class Vote(models.Model):
|
||||
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, related_name="votes", verbose_name=_("candidature")
|
||||
)
|
||||
|
@ -1,5 +1,5 @@
|
||||
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.conf import settings
|
||||
|
||||
|
@ -1,55 +1,57 @@
|
||||
from django.conf.urls import url
|
||||
from django.urls import re_path
|
||||
|
||||
from election.views import *
|
||||
|
||||
urlpatterns = [
|
||||
url(r"^$", ElectionsListView.as_view(), name="list"),
|
||||
url(r"^archived$", ElectionListArchivedView.as_view(), name="list_archived"),
|
||||
url(r"^add$", ElectionCreateView.as_view(), name="create"),
|
||||
url(r"^(?P<election_id>[0-9]+)/edit$", ElectionUpdateView.as_view(), name="update"),
|
||||
url(
|
||||
re_path(r"^$", ElectionsListView.as_view(), name="list"),
|
||||
re_path(r"^archived$", ElectionListArchivedView.as_view(), name="list_archived"),
|
||||
re_path(r"^add$", ElectionCreateView.as_view(), name="create"),
|
||||
re_path(
|
||||
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"
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^(?P<election_id>[0-9]+)/list/add$",
|
||||
ElectionListCreateView.as_view(),
|
||||
name="create_list",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^(?P<list_id>[0-9]+)/list/delete$",
|
||||
ElectionListDeleteView.as_view(),
|
||||
name="delete_list",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^(?P<election_id>[0-9]+)/role/create$",
|
||||
RoleCreateView.as_view(),
|
||||
name="create_role",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
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$",
|
||||
RoleDeleteView.as_view(),
|
||||
name="delete_role",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^(?P<election_id>[0-9]+)/candidate/add$",
|
||||
CandidatureCreateView.as_view(),
|
||||
name="candidate",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^(?P<candidature_id>[0-9]+)/candidate/edit$",
|
||||
CandidatureUpdateView.as_view(),
|
||||
name="update_candidate",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^(?P<candidature_id>[0-9]+)/candidate/delete$",
|
||||
CandidatureDeleteView.as_view(),
|
||||
name="delete_candidate",
|
||||
),
|
||||
url(r"^(?P<election_id>[0-9]+)/vote$", VoteFormView.as_view(), name="vote"),
|
||||
url(
|
||||
re_path(r"^(?P<election_id>[0-9]+)/vote$", VoteFormView.as_view(), name="vote"),
|
||||
re_path(
|
||||
r"^(?P<election_id>[0-9]+)/detail$", ElectionDetailView.as_view(), name="detail"
|
||||
),
|
||||
]
|
||||
|
@ -2,7 +2,7 @@ from django.shortcuts import get_object_or_404
|
||||
from django.views.generic import ListView, DetailView
|
||||
from django.views.generic.edit import UpdateView, CreateView
|
||||
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.core.exceptions import PermissionDenied
|
||||
from django.db import transaction
|
||||
@ -28,23 +28,10 @@ class LimitedCheckboxField(forms.ModelMultipleChoiceField):
|
||||
automatic backend verification
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
queryset,
|
||||
max_choice,
|
||||
required=True,
|
||||
widget=None,
|
||||
label=None,
|
||||
initial=None,
|
||||
help_text="",
|
||||
*args,
|
||||
**kwargs
|
||||
):
|
||||
def __init__(self, queryset, max_choice, **kwargs):
|
||||
self.max_choice = max_choice
|
||||
widget = forms.CheckboxSelectMultiple()
|
||||
super(LimitedCheckboxField, self).__init__(
|
||||
queryset, None, required, widget, label, initial, help_text, *args, **kwargs
|
||||
)
|
||||
super(LimitedCheckboxField, self).__init__(queryset, **kwargs)
|
||||
|
||||
def clean(self, value):
|
||||
qs = super(LimitedCheckboxField, self).clean(value)
|
||||
@ -181,22 +168,25 @@ class ElectionForm(forms.ModelForm):
|
||||
)
|
||||
|
||||
start_date = forms.DateTimeField(
|
||||
["%Y-%m-%d %H:%M:%S"],
|
||||
input_formats=["%Y-%m-%d %H:%M:%S"],
|
||||
label=_("Start date"),
|
||||
widget=SelectDateTime,
|
||||
required=True,
|
||||
)
|
||||
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(
|
||||
["%Y-%m-%d %H:%M:%S"],
|
||||
input_formats=["%Y-%m-%d %H:%M:%S"],
|
||||
label=_("Start candidature"),
|
||||
widget=SelectDateTime,
|
||||
required=True,
|
||||
)
|
||||
end_candidature = forms.DateTimeField(
|
||||
["%Y-%m-%d %H:%M:%S"],
|
||||
input_formats=["%Y-%m-%d %H:%M:%S"],
|
||||
label=_("End candidature"),
|
||||
widget=SelectDateTime,
|
||||
required=True,
|
||||
@ -550,7 +540,7 @@ class CandidatureUpdateView(CanEditMixin, UpdateView):
|
||||
self.form = self.get_form()
|
||||
self.remove_fields()
|
||||
if (
|
||||
request.user.is_authenticated()
|
||||
request.user.is_authenticated
|
||||
and request.user.can_edit(self.object)
|
||||
and self.form.is_valid()
|
||||
):
|
||||
@ -594,7 +584,7 @@ class RoleUpdateView(CanEditMixin, UpdateView):
|
||||
self.form = self.get_form()
|
||||
self.remove_fields()
|
||||
if (
|
||||
request.user.is_authenticated()
|
||||
request.user.is_authenticated
|
||||
and request.user.can_edit(self.object)
|
||||
and self.form.is_valid()
|
||||
):
|
||||
|
@ -6,6 +6,7 @@ from django.utils.timezone import utc
|
||||
from django.conf import settings
|
||||
import django.utils.timezone
|
||||
import datetime
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
@ -52,6 +53,7 @@ class Migration(migrations.Migration):
|
||||
(
|
||||
"owner_club",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
to="club.Club",
|
||||
verbose_name="owner club",
|
||||
related_name="owned_forums",
|
||||
@ -61,7 +63,11 @@ class Migration(migrations.Migration):
|
||||
(
|
||||
"parent",
|
||||
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",
|
||||
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",
|
||||
models.ForeignKey(related_name="metas", to="forum.ForumMessage"),
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="metas",
|
||||
to="forum.ForumMessage",
|
||||
),
|
||||
),
|
||||
(
|
||||
"user",
|
||||
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",
|
||||
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"]},
|
||||
),
|
||||
@ -209,7 +232,9 @@ class Migration(migrations.Migration):
|
||||
(
|
||||
"user",
|
||||
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(
|
||||
model_name="forummessage",
|
||||
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",
|
||||
),
|
||||
),
|
||||
]
|
||||
|
@ -26,7 +26,7 @@ from django.db import models
|
||||
from django.conf import settings
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
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.functional import cached_property
|
||||
|
||||
@ -58,12 +58,19 @@ class Forum(models.Model):
|
||||
name = models.CharField(_("name"), max_length=64)
|
||||
description = models.CharField(_("description"), max_length=512, default="")
|
||||
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(
|
||||
Club,
|
||||
related_name="owned_forums",
|
||||
verbose_name=_("owner club"),
|
||||
default=settings.SITH_MAIN_CLUB_ID,
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
edit_groups = models.ManyToManyField(
|
||||
Group,
|
||||
@ -145,8 +152,8 @@ class Forum(models.Model):
|
||||
"""Copy, if possible, the rights of the parent folder"""
|
||||
if self.parent is not None:
|
||||
self.owner_club = self.parent.owner_club
|
||||
self.edit_groups = self.parent.edit_groups.all()
|
||||
self.view_groups = self.parent.view_groups.all()
|
||||
self.edit_groups.set(self.parent.edit_groups.all())
|
||||
self.view_groups.set(self.parent.view_groups.all())
|
||||
self.save()
|
||||
|
||||
_club_memberships = {} # This cache is particularly efficient:
|
||||
@ -226,8 +233,10 @@ class Forum(models.Model):
|
||||
|
||||
|
||||
class ForumTopic(models.Model):
|
||||
forum = models.ForeignKey(Forum, related_name="topics")
|
||||
author = models.ForeignKey(User, related_name="forum_topics")
|
||||
forum = models.ForeignKey(Forum, related_name="topics", on_delete=models.CASCADE)
|
||||
author = models.ForeignKey(
|
||||
User, related_name="forum_topics", on_delete=models.CASCADE
|
||||
)
|
||||
description = models.CharField(_("description"), max_length=256, default="")
|
||||
subscribed_users = models.ManyToManyField(
|
||||
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
|
||||
"""
|
||||
|
||||
topic = models.ForeignKey(ForumTopic, related_name="messages")
|
||||
author = models.ForeignKey(User, related_name="forum_messages")
|
||||
topic = models.ForeignKey(
|
||||
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)
|
||||
message = models.TextField(_("message"), default="")
|
||||
date = models.DateTimeField(_("date"), default=timezone.now)
|
||||
@ -386,8 +399,12 @@ MESSAGE_META_ACTIONS = [
|
||||
|
||||
|
||||
class ForumMessageMeta(models.Model):
|
||||
user = models.ForeignKey(User, related_name="forum_message_metas")
|
||||
message = models.ForeignKey(ForumMessage, related_name="metas")
|
||||
user = models.ForeignKey(
|
||||
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)
|
||||
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 = 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"),
|
||||
default=datetime(
|
||||
|
@ -22,64 +22,68 @@
|
||||
#
|
||||
#
|
||||
|
||||
from django.conf.urls import url
|
||||
from django.urls import re_path
|
||||
|
||||
from forum.views import *
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
url(r"^$", ForumMainView.as_view(), name="main"),
|
||||
url(r"^search/$", ForumSearchView.as_view(), name="search"),
|
||||
url(r"^new_forum$", ForumCreateView.as_view(), name="new_forum"),
|
||||
url(r"^mark_all_as_read$", ForumMarkAllAsRead.as_view(), name="mark_all_as_read"),
|
||||
url(r"^last_unread$", ForumLastUnread.as_view(), name="last_unread"),
|
||||
url(r"^favorite_topics$", ForumFavoriteTopics.as_view(), name="favorite_topics"),
|
||||
url(r"^(?P<forum_id>[0-9]+)$", ForumDetailView.as_view(), name="view_forum"),
|
||||
url(r"^(?P<forum_id>[0-9]+)/edit$", ForumEditView.as_view(), name="edit_forum"),
|
||||
url(
|
||||
re_path(r"^$", ForumMainView.as_view(), name="main"),
|
||||
re_path(r"^search/$", ForumSearchView.as_view(), name="search"),
|
||||
re_path(r"^new_forum$", ForumCreateView.as_view(), name="new_forum"),
|
||||
re_path(
|
||||
r"^mark_all_as_read$", ForumMarkAllAsRead.as_view(), name="mark_all_as_read"
|
||||
),
|
||||
re_path(r"^last_unread$", ForumLastUnread.as_view(), name="last_unread"),
|
||||
re_path(
|
||||
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"
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^(?P<forum_id>[0-9]+)/new_topic$",
|
||||
ForumTopicCreateView.as_view(),
|
||||
name="new_topic",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^topic/(?P<topic_id>[0-9]+)$",
|
||||
ForumTopicDetailView.as_view(),
|
||||
name="view_topic",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^topic/(?P<topic_id>[0-9]+)/edit$",
|
||||
ForumTopicEditView.as_view(),
|
||||
name="edit_topic",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^topic/(?P<topic_id>[0-9]+)/new_message$",
|
||||
ForumMessageCreateView.as_view(),
|
||||
name="new_message",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^topic/(?P<topic_id>[0-9]+)/toggle_subscribe$",
|
||||
ForumTopicSubscribeView.as_view(),
|
||||
name="toggle_subscribe_topic",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^message/(?P<message_id>[0-9]+)$",
|
||||
ForumMessageView.as_view(),
|
||||
name="view_message",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^message/(?P<message_id>[0-9]+)/edit$",
|
||||
ForumMessageEditView.as_view(),
|
||||
name="edit_message",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^message/(?P<message_id>[0-9]+)/delete$",
|
||||
ForumMessageDeleteView.as_view(),
|
||||
name="delete_message",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^message/(?P<message_id>[0-9]+)/undelete$",
|
||||
ForumMessageUndeleteView.as_view(),
|
||||
name="undelete_message",
|
||||
|
@ -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.detail import SingleObjectMixin
|
||||
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.conf import settings
|
||||
from django import forms
|
||||
|
@ -2,6 +2,7 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
@ -25,6 +26,7 @@ class Migration(migrations.Migration):
|
||||
(
|
||||
"counter",
|
||||
models.OneToOneField(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="launderette",
|
||||
verbose_name="counter",
|
||||
to="counter.Counter",
|
||||
@ -61,6 +63,7 @@ class Migration(migrations.Migration):
|
||||
(
|
||||
"launderette",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
verbose_name="launderette",
|
||||
to="launderette.Launderette",
|
||||
related_name="machines",
|
||||
@ -93,6 +96,7 @@ class Migration(migrations.Migration):
|
||||
(
|
||||
"machine",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
verbose_name="machine",
|
||||
to="launderette.Machine",
|
||||
related_name="slots",
|
||||
@ -131,6 +135,7 @@ class Migration(migrations.Migration):
|
||||
(
|
||||
"launderette",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
verbose_name="launderette",
|
||||
to="launderette.Launderette",
|
||||
related_name="tokens",
|
||||
@ -139,6 +144,7 @@ class Migration(migrations.Migration):
|
||||
(
|
||||
"user",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
null=True,
|
||||
related_name="tokens",
|
||||
verbose_name="user",
|
||||
@ -153,6 +159,7 @@ class Migration(migrations.Migration):
|
||||
model_name="slot",
|
||||
name="token",
|
||||
field=models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
null=True,
|
||||
related_name="slots",
|
||||
verbose_name="token",
|
||||
@ -164,7 +171,10 @@ class Migration(migrations.Migration):
|
||||
model_name="slot",
|
||||
name="user",
|
||||
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(
|
||||
|
@ -25,7 +25,7 @@
|
||||
from django.db import models, DataError
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.conf import settings
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.urls import reverse
|
||||
|
||||
from counter.models import Counter
|
||||
from core.models import User
|
||||
@ -37,7 +37,10 @@ from club.models import Club
|
||||
class Launderette(models.Model):
|
||||
name = models.CharField(_("name"), max_length=30)
|
||||
counter = models.OneToOneField(
|
||||
Counter, verbose_name=_("counter"), related_name="launderette"
|
||||
Counter,
|
||||
verbose_name=_("counter"),
|
||||
related_name="launderette",
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
class Meta:
|
||||
@ -89,7 +92,10 @@ class Launderette(models.Model):
|
||||
class Machine(models.Model):
|
||||
name = models.CharField(_("name"), max_length=30)
|
||||
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"), max_length=10, choices=settings.SITH_LAUNDERETTE_MACHINE_TYPES
|
||||
@ -124,14 +130,22 @@ class Machine(models.Model):
|
||||
class Token(models.Model):
|
||||
name = models.CharField(_("name"), max_length=5)
|
||||
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"), max_length=10, choices=settings.SITH_LAUNDERETTE_MACHINE_TYPES
|
||||
)
|
||||
borrow_date = models.DateTimeField(_("borrow date"), null=True, blank=True)
|
||||
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:
|
||||
@ -182,12 +196,22 @@ class Slot(models.Model):
|
||||
_("type"), max_length=10, choices=settings.SITH_LAUNDERETTE_MACHINE_TYPES
|
||||
)
|
||||
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, 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:
|
||||
verbose_name = _("Slot")
|
||||
|
@ -22,53 +22,53 @@
|
||||
#
|
||||
#
|
||||
|
||||
from django.conf.urls import url
|
||||
from django.urls import re_path
|
||||
|
||||
from launderette.views import *
|
||||
|
||||
urlpatterns = [
|
||||
# views
|
||||
url(r"^$", LaunderetteMainView.as_view(), name="launderette_main"),
|
||||
url(
|
||||
re_path(r"^$", LaunderetteMainView.as_view(), name="launderette_main"),
|
||||
re_path(
|
||||
r"^slot/(?P<slot_id>[0-9]+)/delete$",
|
||||
SlotDeleteView.as_view(),
|
||||
name="delete_slot",
|
||||
),
|
||||
url(r"^book$", LaunderetteBookMainView.as_view(), name="book_main"),
|
||||
url(
|
||||
re_path(r"^book$", LaunderetteBookMainView.as_view(), name="book_main"),
|
||||
re_path(
|
||||
r"^book/(?P<launderette_id>[0-9]+)$",
|
||||
LaunderetteBookView.as_view(),
|
||||
name="book_slot",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^(?P<launderette_id>[0-9]+)/click$",
|
||||
LaunderetteMainClickView.as_view(),
|
||||
name="main_click",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^(?P<launderette_id>[0-9]+)/click/(?P<user_id>[0-9]+)$",
|
||||
LaunderetteClickView.as_view(),
|
||||
name="click",
|
||||
),
|
||||
url(r"^admin$", LaunderetteListView.as_view(), name="launderette_list"),
|
||||
url(
|
||||
re_path(r"^admin$", LaunderetteListView.as_view(), name="launderette_list"),
|
||||
re_path(
|
||||
r"^admin/(?P<launderette_id>[0-9]+)$",
|
||||
LaunderetteAdminView.as_view(),
|
||||
name="launderette_admin",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^admin/(?P<launderette_id>[0-9]+)/edit$",
|
||||
LaunderetteEditView.as_view(),
|
||||
name="launderette_edit",
|
||||
),
|
||||
url(r"^admin/new$", LaunderetteCreateView.as_view(), name="launderette_new"),
|
||||
url(r"^admin/machine/new$", MachineCreateView.as_view(), name="machine_new"),
|
||||
url(
|
||||
re_path(r"^admin/new$", LaunderetteCreateView.as_view(), name="launderette_new"),
|
||||
re_path(r"^admin/machine/new$", MachineCreateView.as_view(), name="machine_new"),
|
||||
re_path(
|
||||
r"^admin/machine/(?P<machine_id>[0-9]+)/edit$",
|
||||
MachineEditView.as_view(),
|
||||
name="machine_edit",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^admin/machine/(?P<machine_id>[0-9]+)/delete$",
|
||||
MachineDeleteView.as_view(),
|
||||
name="machine_delete",
|
||||
|
@ -30,7 +30,7 @@ from django.views.generic import ListView, DetailView, TemplateView
|
||||
from django.views.generic.edit import UpdateView, CreateView, DeleteView, BaseFormView
|
||||
from django.utils.translation import ugettext as _
|
||||
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.db import transaction, DataError
|
||||
from django import forms
|
||||
@ -84,7 +84,7 @@ class LaunderetteBookView(CanViewMixin, DetailView):
|
||||
self.object = self.get_object()
|
||||
if "slot_type" in request.POST.keys():
|
||||
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
|
||||
if self.subscriber.is_subscribed:
|
||||
self.date = dateparse.parse_datetime(request.POST["slot"]).replace(
|
||||
|
@ -22,13 +22,13 @@
|
||||
#
|
||||
#
|
||||
|
||||
from django.conf.urls import url
|
||||
from django.urls import re_path
|
||||
|
||||
from matmat.views import *
|
||||
|
||||
urlpatterns = [
|
||||
url(r"^$", SearchNormalFormView.as_view(), name="search"),
|
||||
url(r"^reverse$", SearchReverseFormView.as_view(), name="search_reverse"),
|
||||
url(r"^quick$", SearchQuickFormView.as_view(), name="search_quick"),
|
||||
url(r"^clear$", SearchClearFormView.as_view(), name="search_clear"),
|
||||
re_path(r"^$", SearchNormalFormView.as_view(), name="search"),
|
||||
re_path(r"^reverse$", SearchReverseFormView.as_view(), name="search_reverse"),
|
||||
re_path(r"^quick$", SearchQuickFormView.as_view(), name="search_quick"),
|
||||
re_path(r"^clear$", SearchClearFormView.as_view(), name="search_clear"),
|
||||
]
|
||||
|
@ -29,7 +29,7 @@ from django.views.generic.edit import FormView
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.views.generic.detail import SingleObjectMixin
|
||||
from django.http.response import HttpResponseRedirect
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.urls import reverse
|
||||
from django import forms
|
||||
|
||||
from core.models import User
|
||||
@ -70,7 +70,11 @@ class SearchForm(forms.ModelForm):
|
||||
}
|
||||
|
||||
sex = forms.ChoiceField(
|
||||
[("MAN", _("Man")), ("WOMAN", _("Woman")), ("INDIFFERENT", _("Indifferent"))],
|
||||
choices=[
|
||||
("MAN", _("Man")),
|
||||
("WOMAN", _("Woman")),
|
||||
("INDIFFERENT", _("Indifferent")),
|
||||
],
|
||||
widget=forms.RadioSelect,
|
||||
initial="INDIFFERENT",
|
||||
label=_("Sex"),
|
||||
|
@ -28,7 +28,7 @@ from django.utils import timezone
|
||||
from django.core import validators
|
||||
from django.conf import settings
|
||||
from django.utils.functional import cached_property
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.urls import reverse
|
||||
|
||||
from rest_framework import serializers
|
||||
|
||||
@ -61,6 +61,7 @@ class UV(models.Model):
|
||||
verbose_name=_("author"),
|
||||
null=False,
|
||||
blank=False,
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
credit_type = models.CharField(
|
||||
_("credit type"),
|
||||
@ -210,8 +211,11 @@ class UVComment(models.Model):
|
||||
verbose_name=_("author"),
|
||||
null=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)
|
||||
grade_global = models.IntegerField(
|
||||
_("global grade"),
|
||||
@ -283,8 +287,12 @@ class UVResult(models.Model):
|
||||
a semester (P/A)20xx
|
||||
"""
|
||||
|
||||
uv = models.ForeignKey(UV, related_name="results", verbose_name=_("uv"))
|
||||
user = models.ForeignKey(User, related_name="uv_results", verbose_name=("user"))
|
||||
uv = models.ForeignKey(
|
||||
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"),
|
||||
max_length=10,
|
||||
@ -310,7 +318,10 @@ class UVCommentReport(models.Model):
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
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"))
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
from django.conf import settings
|
||||
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.core.management import call_command
|
||||
|
||||
|
@ -22,33 +22,33 @@
|
||||
#
|
||||
#
|
||||
|
||||
from django.conf.urls import url
|
||||
from django.urls import re_path
|
||||
|
||||
from pedagogy.views import *
|
||||
|
||||
urlpatterns = [
|
||||
# Urls displaying the actual application for visitors
|
||||
url(r"^$", UVListView.as_view(), name="guide"),
|
||||
url(r"^uv/(?P<uv_id>[0-9]+)$", UVDetailFormView.as_view(), name="uv_detail"),
|
||||
url(
|
||||
re_path(r"^$", UVListView.as_view(), name="guide"),
|
||||
re_path(r"^uv/(?P<uv_id>[0-9]+)$", UVDetailFormView.as_view(), name="uv_detail"),
|
||||
re_path(
|
||||
r"^comment/(?P<comment_id>[0-9]+)/edit$",
|
||||
UVCommentUpdateView.as_view(),
|
||||
name="comment_update",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^comment/(?P<comment_id>[0-9]+)/delete$",
|
||||
UVCommentDeleteView.as_view(),
|
||||
name="comment_delete",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^comment/(?P<comment_id>[0-9]+)/report$",
|
||||
UVCommentReportCreateView.as_view(),
|
||||
name="comment_report",
|
||||
),
|
||||
# Moderation
|
||||
url(r"^moderation$", UVModerationFormView.as_view(), name="moderation"),
|
||||
re_path(r"^moderation$", UVModerationFormView.as_view(), name="moderation"),
|
||||
# Administration : Create Update Delete Edit
|
||||
url(r"^uv/create$", UVCreateView.as_view(), name="uv_create"),
|
||||
url(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/create$", UVCreateView.as_view(), name="uv_create"),
|
||||
re_path(r"^uv/(?P<uv_id>[0-9]+)/delete$", UVDeleteView.as_view(), name="uv_delete"),
|
||||
re_path(r"^uv/(?P<uv_id>[0-9]+)/edit$", UVUpdateView.as_view(), name="uv_update"),
|
||||
]
|
||||
|
@ -33,7 +33,7 @@ from django.views.generic import (
|
||||
from django.utils import html
|
||||
from django.http import HttpResponse
|
||||
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.conf import settings
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
# Django 1.11 LTS is required
|
||||
Django >=1.11, <2.0
|
||||
Django >=2.2, <3.0
|
||||
Pillow
|
||||
mistune
|
||||
django-jinja
|
||||
pyopenssl
|
||||
pytz
|
||||
djangorestframework <3.10
|
||||
djangorestframework
|
||||
django-phonenumber-field
|
||||
phonenumbers
|
||||
django-ajax-selects
|
||||
|
@ -22,13 +22,13 @@
|
||||
#
|
||||
#
|
||||
|
||||
from django.conf.urls import url
|
||||
from django.urls import re_path
|
||||
|
||||
from rootplace.views import *
|
||||
|
||||
urlpatterns = [
|
||||
url(r"^merge$", MergeUsersView.as_view(), name="merge"),
|
||||
url(
|
||||
re_path(r"^merge$", MergeUsersView.as_view(), name="merge"),
|
||||
re_path(
|
||||
r"^forum/messages/delete$",
|
||||
DeleteAllForumUserMessagesView.as_view(),
|
||||
name="delete_forum_messages",
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.views.generic.edit import FormView
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.urls import reverse
|
||||
from django import forms
|
||||
from django.core.exceptions import PermissionDenied
|
||||
|
||||
|
@ -3,6 +3,7 @@ from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
from django.conf import settings
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
@ -28,12 +29,16 @@ class Migration(migrations.Migration):
|
||||
(
|
||||
"picture",
|
||||
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",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="pictures",
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
verbose_name="user",
|
||||
|
@ -23,7 +23,7 @@
|
||||
#
|
||||
|
||||
from django.db import models
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.urls import reverse
|
||||
from django.core.cache import cache
|
||||
from django.conf import settings
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
@ -240,7 +240,12 @@ class PeoplePictureRelation(models.Model):
|
||||
"""
|
||||
|
||||
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,
|
||||
@ -248,6 +253,7 @@ class PeoplePictureRelation(models.Model):
|
||||
related_name="people",
|
||||
null=False,
|
||||
blank=False,
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
class Meta:
|
||||
|
28
sas/urls.py
28
sas/urls.py
@ -22,40 +22,40 @@
|
||||
#
|
||||
#
|
||||
|
||||
from django.conf.urls import url
|
||||
from django.urls import re_path
|
||||
|
||||
from sas.views import *
|
||||
|
||||
urlpatterns = [
|
||||
url(r"^$", SASMainView.as_view(), name="main"),
|
||||
url(r"^moderation$", ModerationView.as_view(), name="moderation"),
|
||||
url(r"^album/(?P<album_id>[0-9]+)$", AlbumView.as_view(), name="album"),
|
||||
url(
|
||||
re_path(r"^$", SASMainView.as_view(), name="main"),
|
||||
re_path(r"^moderation$", ModerationView.as_view(), name="moderation"),
|
||||
re_path(r"^album/(?P<album_id>[0-9]+)$", AlbumView.as_view(), name="album"),
|
||||
re_path(
|
||||
r"^album/(?P<album_id>[0-9]+)/upload$",
|
||||
AlbumUploadView.as_view(),
|
||||
name="album_upload",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
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"),
|
||||
url(r"^picture/(?P<picture_id>[0-9]+)$", PictureView.as_view(), name="picture"),
|
||||
url(
|
||||
re_path(r"^album/(?P<album_id>[0-9]+)/preview$", send_album, name="album_preview"),
|
||||
re_path(r"^picture/(?P<picture_id>[0-9]+)$", PictureView.as_view(), name="picture"),
|
||||
re_path(
|
||||
r"^picture/(?P<picture_id>[0-9]+)/edit$",
|
||||
PictureEditView.as_view(),
|
||||
name="picture_edit",
|
||||
),
|
||||
url(r"^picture/(?P<picture_id>[0-9]+)/download$", send_pict, name="download"),
|
||||
url(
|
||||
re_path(r"^picture/(?P<picture_id>[0-9]+)/download$", send_pict, name="download"),
|
||||
re_path(
|
||||
r"^picture/(?P<picture_id>[0-9]+)/download/compressed$",
|
||||
send_compressed,
|
||||
name="download_compressed",
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
r"^picture/(?P<picture_id>[0-9]+)/download/thumb$",
|
||||
send_thumb,
|
||||
name="download_thumb",
|
||||
),
|
||||
# url(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'^album/new$', AlbumCreateView.as_view(), name='album_new'),
|
||||
# re_path(r'^(?P<club_id>[0-9]+)/$', ClubView.as_view(), name='club_view'),
|
||||
]
|
||||
|
12
sas/views.py
12
sas/views.py
@ -24,7 +24,7 @@
|
||||
|
||||
from django.shortcuts import redirect
|
||||
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 django.views.generic import DetailView, TemplateView
|
||||
from django.views.generic.edit import UpdateView, FormMixin, FormView
|
||||
@ -78,7 +78,7 @@ class SASForm(forms.Form):
|
||||
file=f,
|
||||
owner=owner,
|
||||
mime_type=f.content_type,
|
||||
size=f._size,
|
||||
size=f.size,
|
||||
is_folder=False,
|
||||
is_moderated=automodere,
|
||||
)
|
||||
@ -117,7 +117,7 @@ class SASMainView(FormView):
|
||||
parent = SithFile.objects.filter(id=settings.SITH_SAS_ROOT_DIR_ID).first()
|
||||
files = request.FILES.getlist("images")
|
||||
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
|
||||
):
|
||||
if self.form.is_valid():
|
||||
@ -176,7 +176,7 @@ class PictureView(CanViewMixin, DetailView, FormMixin):
|
||||
def post(self, request, *args, **kwargs):
|
||||
self.object = self.get_object()
|
||||
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():
|
||||
for uid in self.form.cleaned_data["users"]:
|
||||
u = User.objects.filter(id=uid).first()
|
||||
@ -233,7 +233,7 @@ class AlbumUploadView(CanViewMixin, DetailView, FormMixin):
|
||||
self.form = self.get_form()
|
||||
parent = SithFile.objects.filter(id=self.object.id).first()
|
||||
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():
|
||||
self.form.process(
|
||||
parent=parent,
|
||||
@ -279,7 +279,7 @@ class AlbumView(CanViewMixin, DetailView, FormMixin):
|
||||
FileView.handle_clipboard(request, self.object)
|
||||
parent = SithFile.objects.filter(id=self.object.id).first()
|
||||
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():
|
||||
self.form.process(
|
||||
parent=parent,
|
||||
|
@ -101,7 +101,6 @@ MIDDLEWARE = (
|
||||
"django.middleware.common.CommonMiddleware",
|
||||
"django.middleware.csrf.CsrfViewMiddleware",
|
||||
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
||||
"django.contrib.auth.middleware.SessionAuthenticationMiddleware",
|
||||
"django.contrib.messages.middleware.MessageMiddleware",
|
||||
"django.middleware.locale.LocaleMiddleware",
|
||||
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
||||
|
69
sith/urls.py
69
sith/urls.py
@ -37,11 +37,11 @@ Including another URLconf
|
||||
1. Add an import: from blog import urls as 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.conf.urls.static import static
|
||||
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
|
||||
|
||||
js_info_dict = {"packages": ("sith",)}
|
||||
@ -51,48 +51,43 @@ handler404 = "core.views.not_found"
|
||||
handler500 = "core.views.internal_servor_error"
|
||||
|
||||
urlpatterns = [
|
||||
url(r"^", include("core.urls", namespace="core", app_name="core")),
|
||||
url(
|
||||
r"^rootplace/",
|
||||
include("rootplace.urls", namespace="rootplace", app_name="rootplace"),
|
||||
re_path(r"^", include(("core.urls", "core"), namespace="core")),
|
||||
re_path(
|
||||
r"^rootplace/", include(("rootplace.urls", "rootplace"), namespace="rootplace")
|
||||
),
|
||||
url(
|
||||
re_path(
|
||||
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")),
|
||||
url(r"^club/", include("club.urls", namespace="club", app_name="club")),
|
||||
url(r"^counter/", include("counter.urls", namespace="counter", app_name="counter")),
|
||||
url(r"^stock/", include("stock.urls", namespace="stock", app_name="stock")),
|
||||
url(
|
||||
re_path(r"^com/", include(("com.urls", "com"), namespace="com")),
|
||||
re_path(r"^club/", include(("club.urls", "club"), namespace="club")),
|
||||
re_path(r"^counter/", include(("counter.urls", "counter"), namespace="counter")),
|
||||
re_path(r"^stock/", include(("stock.urls", "stock"), namespace="stock")),
|
||||
re_path(
|
||||
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")),
|
||||
url(
|
||||
re_path(r"^eboutic/", include(("eboutic.urls", "eboutic"), namespace="eboutic")),
|
||||
re_path(
|
||||
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")),
|
||||
url(r"^api/v1/", include("api.urls", namespace="api", app_name="api")),
|
||||
url(
|
||||
r"^election/",
|
||||
include("election.urls", namespace="election", app_name="election"),
|
||||
re_path(r"^sas/", include(("sas.urls", "sas"), namespace="sas")),
|
||||
re_path(r"^api/v1/", include(("api.urls", "api"), namespace="api")),
|
||||
re_path(
|
||||
r"^election/", include(("election.urls", "election"), namespace="election")
|
||||
),
|
||||
url(r"^forum/", include("forum.urls", namespace="forum", app_name="forum")),
|
||||
url(r"^trombi/", include("trombi.urls", namespace="trombi", app_name="trombi")),
|
||||
url(
|
||||
r"^matmatronch/", include("matmat.urls", namespace="matmat", app_name="matmat")
|
||||
re_path(r"^forum/", include(("forum.urls", "forum"), namespace="forum")),
|
||||
re_path(r"^trombi/", include(("trombi.urls", "trombi"), namespace="trombi")),
|
||||
re_path(r"^matmatronch/", include(("matmat.urls", "matmat"), namespace="matmat")),
|
||||
re_path(
|
||||
r"^pedagogy/", include(("pedagogy.urls", "pedagogy"), namespace="pedagogy")
|
||||
),
|
||||
url(
|
||||
r"^pedagogy/",
|
||||
include("pedagogy.urls", namespace="pedagogy", app_name="pedagogy"),
|
||||
),
|
||||
url(r"^admin/", include(admin.site.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")),
|
||||
re_path(r"^admin/", admin.site.urls),
|
||||
re_path(r"^ajax_select/", include(ajax_select_urls)),
|
||||
re_path(r"^i18n/", include("django.conf.urls.i18n")),
|
||||
re_path(r"^jsi18n/$", JavaScriptCatalog.as_view(), name="javascript-catalog"),
|
||||
re_path(r"^captcha/", include("captcha.urls")),
|
||||
]
|
||||
|
||||
if settings.DEBUG:
|
||||
@ -100,4 +95,4 @@ if settings.DEBUG:
|
||||
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
|
||||
import debug_toolbar
|
||||
|
||||
urlpatterns += [url(r"^__debug__/", include(debug_toolbar.urls))]
|
||||
urlpatterns += [re_path(r"^__debug__/", include(debug_toolbar.urls))]
|
||||
|
@ -86,6 +86,7 @@ class Migration(migrations.Migration):
|
||||
(
|
||||
"counter",
|
||||
models.OneToOneField(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
verbose_name="counter",
|
||||
related_name="stock",
|
||||
to="counter.Counter",
|
||||
@ -132,7 +133,11 @@ class Migration(migrations.Migration):
|
||||
),
|
||||
(
|
||||
"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",
|
||||
@ -151,7 +156,10 @@ class Migration(migrations.Migration):
|
||||
model_name="shoppinglistitem",
|
||||
name="stockitem_owner",
|
||||
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(
|
||||
@ -170,7 +178,10 @@ class Migration(migrations.Migration):
|
||||
model_name="shoppinglist",
|
||||
name="stock_owner",
|
||||
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",
|
||||
),
|
||||
),
|
||||
]
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
from django.db import models
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.urls import reverse
|
||||
from django.conf import settings
|
||||
|
||||
|
||||
@ -39,7 +39,10 @@ class Stock(models.Model):
|
||||
|
||||
name = models.CharField(_("name"), max_length=64)
|
||||
counter = models.OneToOneField(
|
||||
Counter, verbose_name=_("counter"), related_name="stock"
|
||||
Counter,
|
||||
verbose_name=_("counter"),
|
||||
related_name="stock",
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
@ -79,7 +82,9 @@ class StockItem(models.Model):
|
||||
blank=True,
|
||||
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):
|
||||
return "%s" % (self.name)
|
||||
@ -100,7 +105,9 @@ class ShoppingList(models.Model):
|
||||
name = models.CharField(_("name"), max_length=64)
|
||||
todo = models.BooleanField(_("todo"))
|
||||
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):
|
||||
return "%s (%s)" % (self.name, self.date)
|
||||
@ -122,7 +129,7 @@ class ShoppingListItem(models.Model):
|
||||
related_name="shopping_items_to_buy",
|
||||
)
|
||||
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)
|
||||
type = models.ForeignKey(
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user