Commit 4dadb1db authored by Sli's avatar Sli

django2.2: add default mandatory on_delete on all ForeignKey

parent 2616e8b2
......@@ -110,7 +110,12 @@ class BankAccount(models.Model):
name = models.CharField(_("name"), max_length=30)
iban = models.CharField(_("iban"), max_length=255, blank=True)
number = models.CharField(_("account number"), max_length=255, blank=True)
club = models.ForeignKey(Club, related_name="bank_accounts", verbose_name=_("club"))
club = models.ForeignKey(
Club,
related_name="bank_accounts",
verbose_name=_("club"),
on_delete=models.CASCADE,
)
class Meta:
verbose_name = _("Bank account")
......@@ -136,9 +141,17 @@ class BankAccount(models.Model):
class ClubAccount(models.Model):
name = models.CharField(_("name"), max_length=30)
club = models.ForeignKey(Club, related_name="club_account", verbose_name=_("club"))
club = models.ForeignKey(
Club,
related_name="club_account",
verbose_name=_("club"),
on_delete=models.CASCADE,
)
bank_account = models.ForeignKey(
BankAccount, related_name="club_accounts", verbose_name=_("bank account")
BankAccount,
related_name="club_accounts",
verbose_name=_("bank account"),
on_delete=models.CASCADE,
)
class Meta:
......@@ -203,7 +216,11 @@ class GeneralJournal(models.Model):
name = models.CharField(_("name"), max_length=40)
closed = models.BooleanField(_("is closed"), default=False)
club_account = models.ForeignKey(
ClubAccount, related_name="journals", null=False, verbose_name=_("club account")
ClubAccount,
related_name="journals",
null=False,
verbose_name=_("club account"),
on_delete=models.CASCADE,
)
amount = CurrencyField(_("amount"), default=0)
effective_amount = CurrencyField(_("effective_amount"), default=0)
......@@ -263,7 +280,11 @@ class Operation(models.Model):
number = models.IntegerField(_("number"))
journal = models.ForeignKey(
GeneralJournal, related_name="operations", null=False, verbose_name=_("journal")
GeneralJournal,
related_name="operations",
null=False,
verbose_name=_("journal"),
on_delete=models.CASCADE,
)
amount = CurrencyField(_("amount"))
date = models.DateField(_("date"))
......@@ -282,6 +303,7 @@ class Operation(models.Model):
verbose_name=_("invoice"),
null=True,
blank=True,
on_delete=models.CASCADE,
)
done = models.BooleanField(_("is done"), default=False)
simpleaccounting_type = models.ForeignKey(
......@@ -290,6 +312,7 @@ class Operation(models.Model):
verbose_name=_("simple type"),
null=True,
blank=True,
on_delete=models.CASCADE,
)
accounting_type = models.ForeignKey(
"AccountingType",
......@@ -297,6 +320,7 @@ class Operation(models.Model):
verbose_name=_("accounting type"),
null=True,
blank=True,
on_delete=models.CASCADE,
)
label = models.ForeignKey(
"Label",
......@@ -487,6 +511,7 @@ class SimplifiedAccountingType(models.Model):
AccountingType,
related_name="simplified_types",
verbose_name=_("simplified accounting types"),
on_delete=models.CASCADE,
)
class Meta:
......@@ -518,7 +543,10 @@ class Label(models.Model):
name = models.CharField(_("label"), max_length=64)
club_account = models.ForeignKey(
ClubAccount, related_name="labels", verbose_name=_("club account")
ClubAccount,
related_name="labels",
verbose_name=_("club account"),
on_delete=models.CASCADE,
)
class Meta:
......
......@@ -46,7 +46,9 @@ class Club(models.Model):
id = models.AutoField(primary_key=True, db_index=True)
name = models.CharField(_("name"), max_length=64)
parent = models.ForeignKey("Club", related_name="children", null=True, blank=True)
parent = models.ForeignKey(
"Club", related_name="children", null=True, blank=True, on_delete=models.CASCADE
)
unix_name = models.CharField(
_("unix name"),
max_length=30,
......@@ -75,7 +77,10 @@ class Club(models.Model):
return settings.SITH_GROUP_ROOT_ID
owner_group = models.ForeignKey(
Group, related_name="owned_club", default=get_default_owner_group
Group,
related_name="owned_club",
default=get_default_owner_group,
on_delete=models.CASCADE,
)
edit_groups = models.ManyToManyField(
Group, related_name="editable_club", blank=True
......@@ -261,9 +266,15 @@ class Membership(models.Model):
related_name="memberships",
null=False,
blank=False,
on_delete=models.CASCADE,
)
club = models.ForeignKey(
Club, verbose_name=_("club"), related_name="members", null=False, blank=False
Club,
verbose_name=_("club"),
related_name="members",
null=False,
blank=False,
on_delete=models.CASCADE,
)
start_date = models.DateField(_("start date"), default=timezone.now)
end_date = models.DateField(_("end date"), null=True, blank=True)
......@@ -317,7 +328,12 @@ class Mailing(models.Model):
"""
club = models.ForeignKey(
Club, verbose_name=_("Club"), related_name="mailings", null=False, blank=False
Club,
verbose_name=_("Club"),
related_name="mailings",
null=False,
blank=False,
on_delete=models.CASCADE,
)
email = models.CharField(
_("Email address"),
......@@ -334,7 +350,11 @@ class Mailing(models.Model):
)
is_moderated = models.BooleanField(_("is moderated"), default=False)
moderator = models.ForeignKey(
User, related_name="moderated_mailings", verbose_name=_("moderator"), null=True
User,
related_name="moderated_mailings",
verbose_name=_("moderator"),
null=True,
on_delete=models.CASCADE,
)
def clean(self):
......@@ -409,6 +429,7 @@ class MailingSubscription(models.Model):
related_name="subscriptions",
null=False,
blank=False,
on_delete=models.CASCADE,
)
user = models.ForeignKey(
User,
......@@ -416,6 +437,7 @@ class MailingSubscription(models.Model):
related_name="mailing_subscriptions",
null=True,
blank=True,
on_delete=models.CASCADE,
)
email = models.EmailField(_("Email address"), blank=False, null=False)
......
......@@ -28,7 +28,7 @@ from django.db import models, transaction
from django.db.models import Q
from django.utils.translation import ugettext_lazy as _
from django.utils import timezone
from django.core.urlresolvers import reverse
from django.urls import reverse
from django.conf import settings
from django.contrib.staticfiles.templatetags.staticfiles import static
from django.core.mail import EmailMultiAlternatives
......@@ -71,13 +71,22 @@ class News(models.Model):
type = models.CharField(
_("type"), max_length=16, choices=NEWS_TYPES, default="EVENT"
)
club = models.ForeignKey(Club, related_name="news", verbose_name=_("club"))
club = models.ForeignKey(
Club, related_name="news", verbose_name=_("club"), on_delete=models.CASCADE
)
author = models.ForeignKey(
User, related_name="owned_news", verbose_name=_("author")
User,
related_name="owned_news",
verbose_name=_("author"),
on_delete=models.CASCADE,
)
is_moderated = models.BooleanField(_("is moderated"), default=False)
moderator = models.ForeignKey(
User, related_name="moderated_news", verbose_name=_("moderator"), null=True
User,
related_name="moderated_news",
verbose_name=_("moderator"),
null=True,
on_delete=models.CASCADE,
)
def is_owned_by(self, user):
......@@ -138,7 +147,12 @@ class NewsDate(models.Model):
we don't have to make copies
"""
news = models.ForeignKey(News, related_name="dates", verbose_name=_("news_date"))
news = models.ForeignKey(
News,
related_name="dates",
verbose_name=_("news_date"),
on_delete=models.CASCADE,
)
start_date = models.DateTimeField(_("start_date"), null=True, blank=True)
end_date = models.DateTimeField(_("end_date"), null=True, blank=True)
......@@ -230,15 +244,25 @@ class Weekmail(models.Model):
class WeekmailArticle(models.Model):
weekmail = models.ForeignKey(
Weekmail, related_name="articles", verbose_name=_("weekmail"), null=True
Weekmail,
related_name="articles",
verbose_name=_("weekmail"),
null=True,
on_delete=models.CASCADE,
)
title = models.CharField(_("title"), max_length=64)
content = models.TextField(_("content"))
author = models.ForeignKey(
User, related_name="owned_weekmail_articles", verbose_name=_("author")
User,
related_name="owned_weekmail_articles",
verbose_name=_("author"),
on_delete=models.CASCADE,
)
club = models.ForeignKey(
Club, related_name="weekmail_articles", verbose_name=_("club")
Club,
related_name="weekmail_articles",
verbose_name=_("club"),
on_delete=models.CASCADE,
)
rank = models.IntegerField(_("rank"), default=-1)
......@@ -271,7 +295,11 @@ class Poster(models.Model):
)
file = models.ImageField(_("file"), null=False, upload_to="com/posters")
club = models.ForeignKey(
Club, related_name="posters", verbose_name=_("club"), null=False
Club,
related_name="posters",
verbose_name=_("club"),
null=False,
on_delete=models.CASCADE,
)
screens = models.ManyToManyField(Screen, related_name="posters")
date_begin = models.DateTimeField(blank=False, null=False, default=timezone.now)
......@@ -286,6 +314,7 @@ class Poster(models.Model):
verbose_name=_("moderator"),
null=True,
blank=True,
on_delete=models.CASCADE,
)
def save(self, *args, **kwargs):
......
......@@ -743,7 +743,9 @@ class AnonymousUser(AuthAnonymousUser):
class Preferences(models.Model):
user = models.OneToOneField(User, related_name="_preferences")
user = models.OneToOneField(
User, related_name="_preferences", on_delete=models.CASCADE
)
receive_weekmail = models.BooleanField(
_("do you want to receive the weekmail"), default=False
)
......@@ -777,7 +779,12 @@ def get_thumbnail_directory(instance, filename):
class SithFile(models.Model):
name = models.CharField(_("file name"), max_length=256, blank=False)
parent = models.ForeignKey(
"self", related_name="children", verbose_name=_("parent"), null=True, blank=True
"self",
related_name="children",
verbose_name=_("parent"),
null=True,
blank=True,
on_delete=models.CASCADE,
)
file = models.FileField(
upload_to=get_directory,
......@@ -800,7 +807,12 @@ class SithFile(models.Model):
null=True,
blank=True,
)
owner = models.ForeignKey(User, related_name="owned_files", verbose_name=_("owner"))
owner = models.ForeignKey(
User,
related_name="owned_files",
verbose_name=_("owner"),
on_delete=models.CASCADE,
)
edit_groups = models.ManyToManyField(
Group, related_name="editable_files", verbose_name=_("edit group"), blank=True
)
......@@ -818,6 +830,7 @@ class SithFile(models.Model):
verbose_name=_("owner"),
null=True,
blank=True,
on_delete=models.CASCADE,
)
asked_for_removal = models.BooleanField(_("asked for removal"), default=False)
is_in_sas = models.BooleanField(
......@@ -1133,6 +1146,7 @@ class Page(models.Model):
related_name="owned_page",
verbose_name=_("owner group"),
default=get_default_owner_group,
on_delete=models.CASCADE,
)
edit_groups = models.ManyToManyField(
Group, related_name="editable_page", verbose_name=_("edit group"), blank=True
......@@ -1147,6 +1161,7 @@ class Page(models.Model):
blank=True,
null=True,
default=None,
on_delete=models.CASCADE,
)
lock_timeout = models.DateTimeField(
_("lock_timeout"), null=True, blank=True, default=None
......@@ -1347,8 +1362,8 @@ class PageRev(models.Model):
title = models.CharField(_("page title"), max_length=255, blank=True)
content = models.TextField(_("page content"), blank=True)
date = models.DateTimeField(_("date"), auto_now=True)
author = models.ForeignKey(User, related_name="page_rev")
page = models.ForeignKey(Page, related_name="revisions")
author = models.ForeignKey(User, related_name="page_rev", on_delete=models.CASCADE)
page = models.ForeignKey(Page, related_name="revisions", on_delete=models.CASCADE)
class Meta:
ordering = ["date"]
......@@ -1386,7 +1401,9 @@ class PageRev(models.Model):
class Notification(models.Model):
user = models.ForeignKey(User, related_name="notifications")
user = models.ForeignKey(
User, related_name="notifications", on_delete=models.CASCADE
)
url = models.CharField(_("url"), max_length=255)
param = models.CharField(_("param"), max_length=128, default="")
type = models.CharField(
......@@ -1422,7 +1439,7 @@ class Notification(models.Model):
class Gift(models.Model):
label = models.CharField(_("label"), max_length=255)
date = models.DateTimeField(_("date"), default=timezone.now)
user = models.ForeignKey(User, related_name="gifts")
user = models.ForeignKey(User, related_name="gifts", on_delete=models.CASCADE)
def __str__(self):
return "%s - %s" % (self.translated_label, self.date.strftime("%d %b %Y"))
......
......@@ -163,7 +163,9 @@ class Product(models.Model):
icon = models.ImageField(
upload_to="products", null=True, blank=True, verbose_name=_("icon")
)
club = models.ForeignKey(Club, related_name="products", verbose_name=_("club"))
club = models.ForeignKey(
Club, related_name="products", verbose_name=_("club"), on_delete=models.CASCADE
)
limit_age = models.IntegerField(_("limit age"), default=0)
tray = models.BooleanField(_("tray price"), default=False)
parent_product = models.ForeignKey(
......@@ -209,7 +211,9 @@ class Product(models.Model):
class Counter(models.Model):
name = models.CharField(_("name"), max_length=30)
club = models.ForeignKey(Club, related_name="counters", verbose_name=_("club"))
club = models.ForeignKey(
Club, related_name="counters", verbose_name=_("club"), on_delete=models.CASCADE
)
products = models.ManyToManyField(
Product, related_name="counters", verbose_name=_("products"), blank=True
)
......@@ -344,12 +348,19 @@ class Refilling(models.Model):
Handle the refilling
"""
counter = models.ForeignKey(Counter, related_name="refillings", blank=False)
counter = models.ForeignKey(
Counter, related_name="refillings", blank=False, on_delete=models.CASCADE
)
amount = CurrencyField(_("amount"))
operator = models.ForeignKey(
User, related_name="refillings_as_operator", blank=False
User,
related_name="refillings_as_operator",
blank=False,
on_delete=models.CASCADE,
)
customer = models.ForeignKey(
Customer, related_name="refillings", blank=False, on_delete=models.CASCADE
)
customer = models.ForeignKey(Customer, related_name="refillings", blank=False)
date = models.DateTimeField(_("date"))
payment_method = models.CharField(
_("payment method"),
......@@ -584,9 +595,17 @@ class Permanency(models.Model):
This class aims at storing a traceability of who was barman where and when
"""
user = models.ForeignKey(User, related_name="permanencies", verbose_name=_("user"))
user = models.ForeignKey(
User,
related_name="permanencies",
verbose_name=_("user"),
on_delete=models.CASCADE,
)
counter = models.ForeignKey(
Counter, related_name="permanencies", verbose_name=_("counter")
Counter,
related_name="permanencies",
verbose_name=_("counter"),
on_delete=models.CASCADE,
)
start = models.DateTimeField(_("start date"))
end = models.DateTimeField(_("end date"), null=True, db_index=True)
......@@ -607,10 +626,16 @@ class Permanency(models.Model):
class CashRegisterSummary(models.Model):
user = models.ForeignKey(
User, related_name="cash_summaries", verbose_name=_("user")
User,
related_name="cash_summaries",
verbose_name=_("user"),
on_delete=models.CASCADE,
)
counter = models.ForeignKey(
Counter, related_name="cash_summaries", verbose_name=_("counter")
Counter,
related_name="cash_summaries",
verbose_name=_("counter"),
on_delete=models.CASCADE,
)
date = models.DateTimeField(_("date"))
comment = models.TextField(_("comment"), null=True, blank=True)
......@@ -683,7 +708,10 @@ class CashRegisterSummary(models.Model):
class CashRegisterSummaryItem(models.Model):
cash_summary = models.ForeignKey(
CashRegisterSummary, related_name="items", verbose_name=_("cash summary")
CashRegisterSummary,
related_name="items",
verbose_name=_("cash summary"),
on_delete=models.CASCADE,
)
value = CurrencyField(_("value"))
quantity = models.IntegerField(_("quantity"), default=0)
......@@ -772,4 +800,5 @@ class StudentCard(models.Model):
verbose_name=_("student cards"),
null=False,
blank=False,
on_delete=models.CASCADE,
)
......@@ -37,7 +37,11 @@ class Basket(models.Model):
"""
user = models.ForeignKey(
User, related_name="baskets", verbose_name=_("user"), blank=False
User,
related_name="baskets",
verbose_name=_("user"),
blank=False,
on_delete=models.CASCADE,
)
date = models.DateTimeField(_("date"), auto_now=True)
......@@ -80,7 +84,11 @@ class Invoice(models.Model):
"""
user = models.ForeignKey(
User, related_name="invoices", verbose_name=_("user"), blank=False
User,
related_name="invoices",
verbose_name=_("user"),
blank=False,
on_delete=models.CASCADE,
)
date = models.DateTimeField(_("date"), auto_now=True)
validated = models.BooleanField(_("validated"), default=False)
......@@ -158,10 +166,15 @@ class AbstractBaseItem(models.Model):
class BasketItem(AbstractBaseItem):
basket = models.ForeignKey(Basket, related_name="items", verbose_name=_("basket"))
basket = models.ForeignKey(
Basket, related_name="items", verbose_name=_("basket"), on_delete=models.CASCADE
)
class InvoiceItem(AbstractBaseItem):
invoice = models.ForeignKey(
Invoice, related_name="items", verbose_name=_("invoice")
Invoice,
related_name="items",
verbose_name=_("invoice"),
on_delete=models.CASCADE,
)
......@@ -111,7 +111,10 @@ class Role(OrderedModel):
"""
election = models.ForeignKey(
Election, related_name="roles", verbose_name=_("election")
Election,
related_name="roles",
verbose_name=_("election"),
on_delete=models.CASCADE,
)
title = models.CharField(_("title"), max_length=255)
description = models.TextField(_("description"), null=True, blank=True)
......@@ -155,7 +158,10 @@ class ElectionList(models.Model):
title = models.CharField(_("title"), max_length=255)
election = models.ForeignKey(
Election, related_name="election_lists", verbose_name=_("election")
Election,
related_name="election_lists",
verbose_name=_("election"),
on_delete=models.CASCADE,
)
def can_be_edited_by(self, user):
......@@ -175,13 +181,25 @@ class Candidature(models.Model):
This class is a component of responsability
"""
role = models.ForeignKey(Role, related_name="candidatures", verbose_name=_("role"))
role = models.ForeignKey(
Role,
related_name="candidatures",
verbose_name=_("role"),
on_delete=models.CASCADE,
)
user = models.ForeignKey(
User, verbose_name=_("user"), related_name="candidates", blank=True
User,
verbose_name=_("user"),
related_name="candidates",
blank=True,
on_delete=models.CASCADE,
)
program = models.TextField(_("description"), null=True, blank=True)
election_list = models.ForeignKey(
ElectionList, related_name="candidatures", verbose_name=_("election list")
ElectionList,
related_name="candidatures",
verbose_name=_("election list"),
on_delete=models.CASCADE,
)
def delete(self):
......@@ -201,7 +219,9 @@ class Vote(models.Model):
This class allows to vote for candidates
"""
role = models.ForeignKey(Role, related_name="votes", verbose_name=_("role"))
role = models.ForeignKey(
Role, related_name="votes", verbose_name=_("role"), on_delete=models.CASCADE
)
candidature = models.ManyToManyField(
Candidature, related_name="votes", verbose_name=_("candidature")
)
......
......@@ -58,12 +58,19 @@ class Forum(models.Model):
name = models.CharField(_("name"), max_length=64)
description = models.CharField(_("description"), max_length=512, default="")
is_category = models.BooleanField(_("is a category"), default=False)
parent = models.ForeignKey("Forum", related_name="children", null=True, blank=True)
parent = models.ForeignKey(
"Forum",
related_name="children",
null=True,
blank=True,
on_delete=models.CASCADE,
)
owner_club = models.ForeignKey(
Club,
related_name="owned_forums",
verbose_name=_("owner club"),
default=settings.SITH_MAIN_CLUB_ID,
on_delete=models.CASCADE,
)
edit_groups = models.ManyToManyField(
Group,
......@@ -226,8 +233,10 @@ class Forum(models.Model):
class ForumTopic(models.Model):
forum = models.ForeignKey(Forum, related_name="topics")
author = models.ForeignKey(User, related_name="forum_topics")
forum = models.ForeignKey(Forum, related_name="topics", on_delete=models.CASCADE)
author = models.ForeignKey(
User, related_name="forum_topics", on_delete=models.CASCADE
)
description = models.CharField(_("description"), max_length=256, default="")
subscribed_users = models.ManyToManyField(
User, related_name="favorite_topics", verbose_name=_("subscribed users")
......@@ -291,8 +300,12 @@ class ForumMessage(models.Model):
"A ForumMessage object represents a message in the forum" -- Cpt. Obvious
"""
topic = models.ForeignKey(ForumTopic, related_name="messages")
author = models.ForeignKey(User, related_name="forum_messages")
topic = models.ForeignKey(
ForumTopic, related_name="messages", on_delete=models.CASCADE
)
author = models.ForeignKey(
User, related_name="forum_messages", on_delete=models.CASCADE
)
title = models.CharField(_("title"), default="", max_length=64, blank=True)
message = models.TextField(_("message"), default="")
date = models.DateTimeField(_("date"), default=timezone.now)
......@@ -386,8 +399,12 @@ MESSAGE_META_ACTIONS = [
class ForumMessageMeta(models.Model):
user = models.ForeignKey(User, related_name="forum_message_metas")
message = models.ForeignKey(ForumMessage, related_name="metas")
user = models.ForeignKey(
User, related_name="forum_message_metas", on_delete=models.CASCADE
)
message = models.ForeignKey(
ForumMessage, related_name="metas", on_delete=models.CASCADE
)
date = models.DateTimeField(_("date"), default=timezone.now)
action = models.CharField(_("action"), choices=MESSAGE_META_ACTIONS, max_length=16)
......
......@@ -89,7 +89,10 @@ class Launderette(models.Model):
class Machine(models.Model):
name = models.CharField(_("name"), max_length=30)
launderette = models.ForeignKey(
Launderette, related_name="machines", verbose_name=_("launderette")
Launderette,
related_name="machines",
verbose_name=_("launderette"),
on_delete=models.CASCADE,
)
type = models.CharField(
_("type"), max_length=10, choices=settings.SITH_LAUNDERETTE_MACHINE_TYPES
......@@ -124,14 +127,22 @@ class Machine(models.Model):
class Token(models.Model):
name = models.CharField(_("name"), max_length=5)
launderette = models.ForeignKey(
Launderette, related_name="tokens", verbose_name=_("launderette")
Launderette,
related_name="tokens",
verbose_name=_("launderette"),
on_delete=models.CASCADE,
)
type = models.CharField(
_("type"), max_length=10, choices=settings.SITH_LAUNDERETTE_MACHINE_TYPES
)
borrow_date = models.DateTimeField(_("borrow date"), null=True, blank=True)
user = models.ForeignKey(
User, related_name="tokens", verbose_name=_("user"), null=True, blank=True
User,
related_name="tokens",
verbose_name=_("user"),
null=True,
blank=True,
on_delete=models.CASCADE,
)
class Meta:
......@@ -182,12 +193,22 @@ class Slot(models.Model):
_("type"), max_length=10, choices=settings.SITH_LAUNDERETTE_MACHINE_TYPES
)
machine = models.ForeignKey(
Machine, related_name="slots", verbose_name=_("machine")
Machine,
related_name="slots",
verbose_name=_("machine"),
on_delete=models.CASCADE,
)
token = models.ForeignKey(
Token, related_name="slots", verbose_name=_("token"), blank=True, null=True
Token,
related_name="slots",
verbose_name=_("token"),
blank=True,
null=True,
on_delete=models.CASCADE,
)
user = models.ForeignKey(
User, related_name="slots", verbose_name=_("user"), on_delete=models.CASCADE
)
user = models.ForeignKey(User, related_name="slots", verbose_name=_("user"))
class Meta:
verbose_name = _("Slot")
......
......@@ -61,6 +61,7 @@ class UV(models.Model):
verbose_name=_("author"),
null=False,
blank=False,
on_delete=models.CASCADE,
)
credit_type = models.CharField(
_("credit type"),
......@@ -210,8 +211,11 @@ class UVComment(models.Model):
verbose_name=_("author"),
null=False,
blank=False,
on_delete=models.CASCADE,
)
uv = models.ForeignKey(
UV, related_name="comments", verbose_name=_("uv"), on_delete=models.CASCADE
)
uv = models.ForeignKey(UV, related_name="comments", verbose_name=_("uv"))
comment = models.TextField(_("comment"), blank=True)
grade_global = models.IntegerField(
_("global grade"),
......@@ -283,8 +287,12 @@ class UVResult(models.Model):
a semester (P/A)20xx
"""
uv = models.ForeignKey(UV, related_name="results", verbose_name=_("uv"))
user = models.ForeignKey(User, related_name="uv_results", verbose_name=("user"))
uv = models.ForeignKey(