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