Added type hints to the Mia core application.
This commit is contained in:
parent
c070b11ea2
commit
1be05c2252
@ -25,11 +25,30 @@ class UserConverter:
|
||||
"""The path converter for the user accounts."""
|
||||
regex = ".*"
|
||||
|
||||
def to_python(self, value):
|
||||
def to_python(self, value: str) -> User:
|
||||
"""Returns the user by her log in ID.
|
||||
|
||||
Args:
|
||||
value: The log in ID.
|
||||
|
||||
Returns:
|
||||
The user.
|
||||
|
||||
Raises:
|
||||
ValueError: When the value is invalid
|
||||
"""
|
||||
try:
|
||||
return User.objects.get(login_id=value)
|
||||
except User.DoesNotExist:
|
||||
raise ValueError
|
||||
|
||||
def to_url(self, value):
|
||||
def to_url(self, value: User) -> str:
|
||||
"""Returns the log in ID of a user.
|
||||
|
||||
Args:
|
||||
value: The user.
|
||||
|
||||
Returns:
|
||||
The log in ID.
|
||||
"""
|
||||
return value.login_id
|
||||
|
@ -22,6 +22,7 @@ application.
|
||||
import ipaddress
|
||||
import socket
|
||||
from functools import wraps
|
||||
from typing import Optional
|
||||
|
||||
from django.conf import settings
|
||||
from django.db.models import F
|
||||
@ -35,23 +36,23 @@ from .models import User, Country
|
||||
class AccountBackend:
|
||||
"""The account backend for the django-digest module."""
|
||||
|
||||
def get_partial_digest(self, username):
|
||||
def get_partial_digest(self, username: str) -> Optional[str]:
|
||||
"""Returns the HTTP digest authentication password digest hash
|
||||
of a user.
|
||||
|
||||
Args:
|
||||
username (str): The log in user name.
|
||||
username: The log in user name.
|
||||
|
||||
Return:
|
||||
str: The HTTP digest authentication password hash of
|
||||
the user, or None if the user does not exist.
|
||||
The HTTP digest authentication password hash of the user, or None
|
||||
if the user does not exist.
|
||||
"""
|
||||
user = User.objects.filter(login_id=username).first()
|
||||
if user is None:
|
||||
return None
|
||||
return user.password
|
||||
|
||||
def get_user(self, username):
|
||||
def get_user(self, username: str) -> Optional[User]:
|
||||
"""Returns the user by her log in user name.
|
||||
|
||||
Args:
|
||||
@ -86,7 +87,7 @@ def login_required(function=None):
|
||||
return decorator
|
||||
|
||||
|
||||
def _log_visit(request):
|
||||
def _log_visit(request: HttpRequest) -> None:
|
||||
"""Logs the visit information for the logged-in user.
|
||||
|
||||
Args:
|
||||
@ -106,21 +107,29 @@ def _log_visit(request):
|
||||
request.session["visit_logged"] = True
|
||||
|
||||
|
||||
def _get_remote_ip(request):
|
||||
def _get_remote_ip(request: HttpRequest) -> str:
|
||||
"""Returns the IP of the remote client.
|
||||
|
||||
Args:
|
||||
request: The request.
|
||||
|
||||
Returns:
|
||||
The IP of the remote client.
|
||||
"""
|
||||
x_forwarded_for = request.META.get("HTTP_X_FORWARDED_FOR")
|
||||
if x_forwarded_for:
|
||||
return x_forwarded_for.split(",")[0]
|
||||
return request.META.get('REMOTE_ADDR')
|
||||
|
||||
|
||||
def _get_host(ip):
|
||||
def _get_host(ip: str) -> Optional[str]:
|
||||
"""Look-up the host name by its IP.
|
||||
|
||||
Args:
|
||||
ip (str): The IP
|
||||
ip: The IP
|
||||
|
||||
Returns:
|
||||
str: The host name, or None if the look-up fails.
|
||||
The host name, or None if the look-up fails.
|
||||
"""
|
||||
try:
|
||||
return socket.gethostbyaddr(ip)[0]
|
||||
@ -128,31 +137,30 @@ def _get_host(ip):
|
||||
return None
|
||||
|
||||
|
||||
def _get_country(ip):
|
||||
def _get_country(ip: str) -> Optional[Country]:
|
||||
"""Look-up the country by its IP.
|
||||
|
||||
Args:
|
||||
ip (str): The IP
|
||||
ip: The IP
|
||||
|
||||
Returns:
|
||||
Country: The country.
|
||||
The country.
|
||||
"""
|
||||
code = _get_country_code(ip)
|
||||
try:
|
||||
return Country.objects.get(code=code)
|
||||
except Country.DoesNotExist:
|
||||
pass
|
||||
return None
|
||||
return None
|
||||
|
||||
|
||||
def _get_country_code(ip):
|
||||
def _get_country_code(ip: str) -> Optional[str]:
|
||||
"""Look-up the country code by its IP.
|
||||
|
||||
Args:
|
||||
ip (str): The IP
|
||||
ip: The IP
|
||||
|
||||
Returns:
|
||||
str: The country code, or None if the look-up fails.
|
||||
The country code, or None if the look-up fails.
|
||||
"""
|
||||
try:
|
||||
return geolite2.lookup(ip).country
|
||||
|
@ -75,7 +75,7 @@ class UserForm(forms.Form):
|
||||
if errors:
|
||||
raise forms.ValidationError(errors)
|
||||
|
||||
def _validate_login_id_unique(self):
|
||||
def _validate_login_id_unique(self) -> None:
|
||||
"""Validates whether the log in ID is unique.
|
||||
|
||||
Raises:
|
||||
@ -93,7 +93,7 @@ class UserForm(forms.Form):
|
||||
self.add_error("login_id", error)
|
||||
raise error
|
||||
|
||||
def _validate_password_new_required(self):
|
||||
def _validate_password_new_required(self) -> None:
|
||||
"""Validates whether the password is entered for newly-created users.
|
||||
|
||||
Raises:
|
||||
@ -108,7 +108,7 @@ class UserForm(forms.Form):
|
||||
self.add_error("password", error)
|
||||
raise error
|
||||
|
||||
def _validate_password_login_id_changed_required(self):
|
||||
def _validate_password_login_id_changed_required(self) -> None:
|
||||
"""Validates whether the password is entered for users whose login ID
|
||||
changed.
|
||||
|
||||
@ -129,7 +129,7 @@ class UserForm(forms.Form):
|
||||
self.add_error("password", error)
|
||||
raise error
|
||||
|
||||
def _validate_password2_required(self):
|
||||
def _validate_password2_required(self) -> None:
|
||||
"""Validates whether the second password is entered.
|
||||
|
||||
Raises:
|
||||
@ -145,7 +145,7 @@ class UserForm(forms.Form):
|
||||
self.add_error("password2", error)
|
||||
raise error
|
||||
|
||||
def _validate_passwords_equal(self):
|
||||
def _validate_passwords_equal(self) -> None:
|
||||
"""Validates whether the two passwords are equa.
|
||||
|
||||
Raises:
|
||||
@ -162,7 +162,7 @@ class UserForm(forms.Form):
|
||||
self.add_error("password2", error)
|
||||
raise error
|
||||
|
||||
def _validate_is_disabled_not_oneself(self):
|
||||
def _validate_is_disabled_not_oneself(self) -> None:
|
||||
"""Validates whether the user tries to disable herself
|
||||
|
||||
Raises:
|
||||
|
@ -18,7 +18,6 @@
|
||||
"""The data models of the Mia core application.
|
||||
|
||||
"""
|
||||
import datetime
|
||||
import hashlib
|
||||
|
||||
from dirtyfields import DirtyFieldsMixin
|
||||
@ -57,11 +56,12 @@ class Country(DirtyFieldsMixin, models.Model):
|
||||
return self.code.__str__() + " " + self.name.__str__()
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
def name(self) -> str:
|
||||
"""The country name in the current language."""
|
||||
return get_multi_lingual_attr(self, "name", "en")
|
||||
|
||||
@name.setter
|
||||
def name(self, value):
|
||||
def name(self, value: str) -> None:
|
||||
set_multi_lingual_attr(self, "name", value)
|
||||
|
||||
class Meta:
|
||||
@ -101,11 +101,11 @@ class User(DirtyFieldsMixin, models.Model):
|
||||
USERNAME_FIELD = "login_id"
|
||||
|
||||
@property
|
||||
def is_anonymous(self):
|
||||
def is_anonymous(self) -> bool:
|
||||
return False
|
||||
|
||||
@property
|
||||
def is_authenticated(self):
|
||||
def is_authenticated(self) -> bool:
|
||||
return True
|
||||
|
||||
def set_password(self):
|
||||
@ -142,16 +142,16 @@ class User(DirtyFieldsMixin, models.Model):
|
||||
F"{login_id}:{settings.DIGEST_REALM}:{password}")
|
||||
|
||||
@staticmethod
|
||||
def md5(value):
|
||||
def md5(value: str) -> str:
|
||||
m = hashlib.md5()
|
||||
m.update(value.encode("utf-8"))
|
||||
return m.hexdigest()
|
||||
|
||||
def is_in_use(self):
|
||||
def is_in_use(self) -> bool:
|
||||
"""Returns whether this user is in use.
|
||||
|
||||
Returns:
|
||||
bool: True if this user is in use, or False otherwise.
|
||||
True if this user is in use, or False otherwise.
|
||||
"""
|
||||
for table in connection.introspection.table_names():
|
||||
if self._is_in_use_with(F"SELECT * FROM {table}"
|
||||
@ -163,14 +163,14 @@ class User(DirtyFieldsMixin, models.Model):
|
||||
return True
|
||||
return False
|
||||
|
||||
def _is_in_use_with(self, sql):
|
||||
def _is_in_use_with(self, sql: str) -> bool:
|
||||
"""Returns whether this user is in use with a specific SQL statement.
|
||||
|
||||
Args:
|
||||
sql (str): The SQL query statement
|
||||
sql: The SQL query statement
|
||||
|
||||
Returns:
|
||||
bool: True if this user is in use, or False otherwise.
|
||||
True if this user is in use, or False otherwise.
|
||||
"""
|
||||
with connection.cursor() as cursor:
|
||||
try:
|
||||
|
@ -20,6 +20,8 @@
|
||||
"""
|
||||
import datetime
|
||||
import re
|
||||
from datetime import date
|
||||
from typing import Optional, List, Any, Union
|
||||
|
||||
from django.core.serializers.json import DjangoJSONEncoder
|
||||
from django.template import defaultfilters
|
||||
@ -33,72 +35,73 @@ class Period:
|
||||
"""The template helper for the period chooser.
|
||||
|
||||
Args:
|
||||
spec (str): The current period specification
|
||||
data_start (datetime.date): The available first day of the data.
|
||||
data_end (datetime.date): The available last day of the data.
|
||||
spec: The current period specification
|
||||
data_start: The available first day of the data.
|
||||
data_end: The available last day of the data.
|
||||
|
||||
Raises:
|
||||
ValueError: When the period specification is invalid.
|
||||
"""
|
||||
def __init__(self, spec=None, data_start=None, data_end=None):
|
||||
def __init__(self, spec: str = None, data_start: datetime.date = None,
|
||||
data_end: datetime.date = None):
|
||||
# Raises ValueError
|
||||
self._period = self.Parser(spec)
|
||||
self._data_start = data_start
|
||||
self._data_end = data_end
|
||||
|
||||
@property
|
||||
def spec(self):
|
||||
def spec(self) -> str:
|
||||
"""Returns the period specification.
|
||||
|
||||
Returns:
|
||||
str: The period specification.
|
||||
The period specification.
|
||||
"""
|
||||
return self._period.spec
|
||||
|
||||
@property
|
||||
def start(self):
|
||||
def start(self) -> datetime.date:
|
||||
"""Returns the start day of the currently-specified period.
|
||||
|
||||
Returns:
|
||||
datetime.date: The start day of the currently-specified period.
|
||||
The start day of the currently-specified period.
|
||||
"""
|
||||
return self._period.start
|
||||
|
||||
@property
|
||||
def end(self):
|
||||
def end(self) -> datetime.date:
|
||||
"""Returns the end day of the currently-specified period.
|
||||
|
||||
Returns:
|
||||
datetime.date: The end day of the currently-specified period.
|
||||
The end day of the currently-specified period.
|
||||
"""
|
||||
return self._period.end
|
||||
|
||||
@property
|
||||
def description(self):
|
||||
def description(self) -> str:
|
||||
"""Returns the text description of the currently-specified period.
|
||||
|
||||
Returns:
|
||||
str: The text description of the currently-specified period
|
||||
The text description of the currently-specified period
|
||||
"""
|
||||
return self._period.description
|
||||
|
||||
@property
|
||||
def prep_desc(self):
|
||||
def prep_desc(self) -> str:
|
||||
"""Returns the text description with preposition of the
|
||||
currently-specified period.
|
||||
|
||||
Returns:
|
||||
str: The text description with preposition of the
|
||||
currently-specified period
|
||||
The text description with preposition of the currently-specified
|
||||
period.
|
||||
"""
|
||||
return self._period.prep_desc
|
||||
|
||||
@staticmethod
|
||||
def _get_last_month_start():
|
||||
def _get_last_month_start() -> datetime.date:
|
||||
"""Returns the first day of the last month.
|
||||
|
||||
Returns:
|
||||
datetime.date: The first day of the last month.
|
||||
The first day of the last month.
|
||||
"""
|
||||
today = timezone.localdate()
|
||||
month = today.month - 1
|
||||
@ -109,11 +112,11 @@ class Period:
|
||||
return datetime.date(year, month, 1)
|
||||
|
||||
@staticmethod
|
||||
def _get_next_month_start():
|
||||
def _get_next_month_start() -> datetime.date:
|
||||
"""Returns the first day of the next month.
|
||||
|
||||
Returns:
|
||||
datetime.date: The first day of the next month.
|
||||
The first day of the next month.
|
||||
"""
|
||||
today = timezone.localdate()
|
||||
month = today.month + 1
|
||||
@ -123,12 +126,12 @@ class Period:
|
||||
year = year + 1
|
||||
return datetime.date(year, month, 1)
|
||||
|
||||
def this_month(self):
|
||||
def this_month(self) -> Optional[str]:
|
||||
"""Returns the specification of this month.
|
||||
|
||||
Returns:
|
||||
str|None: The specification of this month, or None if there is no
|
||||
data in or before this month.
|
||||
The specification of this month, or None if there is no data in or
|
||||
before this month.
|
||||
"""
|
||||
if self._data_start is None:
|
||||
return None
|
||||
@ -139,12 +142,12 @@ class Period:
|
||||
return None
|
||||
return dateformat.format(today, "Y-m")
|
||||
|
||||
def last_month(self):
|
||||
def last_month(self) -> Optional[str]:
|
||||
"""Returns the specification of last month.
|
||||
|
||||
Returns:
|
||||
str|None: The specification of last month, or None if there is no
|
||||
data in or before last month.
|
||||
The specification of last month, or None if there is no data in or
|
||||
before last month.
|
||||
"""
|
||||
if self._data_start is None:
|
||||
return None
|
||||
@ -155,25 +158,25 @@ class Period:
|
||||
return None
|
||||
return dateformat.format(last_month_start, "Y-m")
|
||||
|
||||
def since_last_month(self):
|
||||
def since_last_month(self) -> Optional[str]:
|
||||
"""Returns the specification since last month.
|
||||
|
||||
Returns:
|
||||
str|None: The specification since last month, or None if there is
|
||||
no data in or before last month.
|
||||
The specification since last month, or None if there is no data in
|
||||
or before last month.
|
||||
"""
|
||||
last_month = self.last_month()
|
||||
if last_month is None:
|
||||
return None
|
||||
return last_month + "-"
|
||||
|
||||
def has_months_to_choose(self):
|
||||
def has_months_to_choose(self) -> bool:
|
||||
"""Returns whether there are months to choose besides this month and
|
||||
last month.
|
||||
|
||||
Returns:
|
||||
bool: True if there are months to choose besides this month and
|
||||
last month, or False otherwise.
|
||||
True if there are months to choose besides this month and last
|
||||
month, or False otherwise.
|
||||
"""
|
||||
if self._data_start is None:
|
||||
return False
|
||||
@ -183,14 +186,13 @@ class Period:
|
||||
return True
|
||||
return False
|
||||
|
||||
def chosen_month(self):
|
||||
def chosen_month(self) -> Optional[str]:
|
||||
"""Returns the specification of the chosen month, or None if the
|
||||
current period is not a month or is out of available data range.
|
||||
|
||||
Returns:
|
||||
str|None: The specification of the chosen month, or None if the
|
||||
current period is not a month or is out of available data
|
||||
range.
|
||||
The specification of the chosen month, or None if the current
|
||||
period is not a month or is out of available data range.
|
||||
"""
|
||||
if self._data_start is None:
|
||||
return None
|
||||
@ -203,12 +205,12 @@ class Period:
|
||||
return None
|
||||
return self._period.spec
|
||||
|
||||
def this_year(self):
|
||||
def this_year(self) -> Optional[str]:
|
||||
"""Returns the specification of this year.
|
||||
|
||||
Returns:
|
||||
str|None: The specification of this year, or None if there is no
|
||||
data in or before this year.
|
||||
The specification of this year, or None if there is no data in or
|
||||
before this year.
|
||||
"""
|
||||
if self._data_start is None:
|
||||
return None
|
||||
@ -217,12 +219,12 @@ class Period:
|
||||
return None
|
||||
return str(this_year)
|
||||
|
||||
def last_year(self):
|
||||
def last_year(self) -> Optional[str]:
|
||||
"""Returns the specification of last year.
|
||||
|
||||
Returns:
|
||||
str|None: The specification of last year, or None if there is no
|
||||
data in or before last year.
|
||||
The specification of last year, or None if there is no data in or
|
||||
before last year.
|
||||
"""
|
||||
if self._data_start is None:
|
||||
return None
|
||||
@ -231,13 +233,13 @@ class Period:
|
||||
return None
|
||||
return str(last_year)
|
||||
|
||||
def has_years_to_choose(self):
|
||||
def has_years_to_choose(self) -> bool:
|
||||
"""Returns whether there are years to choose besides this year and
|
||||
last year.
|
||||
|
||||
Returns:
|
||||
bool: True if there are years to choose besides this year and
|
||||
last year, or False otherwise.
|
||||
True if there are years to choose besides this year and last year,
|
||||
or False otherwise.
|
||||
"""
|
||||
if self._data_start is None:
|
||||
return False
|
||||
@ -248,11 +250,12 @@ class Period:
|
||||
return True
|
||||
return False
|
||||
|
||||
def years_to_choose(self):
|
||||
def years_to_choose(self) -> Optional[List[str]]:
|
||||
"""Returns the years to choose besides this year and last year.
|
||||
|
||||
Returns:
|
||||
list[str]: The years to choose besides this year and last year.
|
||||
The years to choose besides this year and last year, or None if
|
||||
there is no data.
|
||||
"""
|
||||
if self._data_start is None:
|
||||
return None
|
||||
@ -263,12 +266,12 @@ class Period:
|
||||
self._data_end.year, this_year, -1)]
|
||||
return after + before[::-1]
|
||||
|
||||
def today(self):
|
||||
def today(self) -> Optional[None]:
|
||||
"""Returns the specification of today.
|
||||
|
||||
Returns:
|
||||
(str): The specification of today, or None if there is no data
|
||||
in or before today.
|
||||
The specification of today, or None if there is no data in or
|
||||
before today.
|
||||
"""
|
||||
if self._data_start is None:
|
||||
return None
|
||||
@ -277,12 +280,12 @@ class Period:
|
||||
return None
|
||||
return dateformat.format(today, "Y-m-d")
|
||||
|
||||
def yesterday(self):
|
||||
def yesterday(self) -> Optional[str]:
|
||||
"""Returns the specification of yesterday.
|
||||
|
||||
Returns:
|
||||
(str): The specification of yesterday, or None if there is no data
|
||||
in or before yesterday.
|
||||
The specification of yesterday, or None if there is no data in or
|
||||
before yesterday.
|
||||
"""
|
||||
if self._data_start is None:
|
||||
return None
|
||||
@ -291,21 +294,21 @@ class Period:
|
||||
return None
|
||||
return dateformat.format(yesterday, "Y-m-d")
|
||||
|
||||
def chosen_day(self):
|
||||
def chosen_day(self) -> str:
|
||||
"""Returns the specification of the chosen day.
|
||||
|
||||
Returns:
|
||||
(str): The specification of the chosen day, or the start day
|
||||
of the period if the current period is not a day.
|
||||
The specification of the chosen day, or the start day of the period
|
||||
if the current period is not a day.
|
||||
"""
|
||||
return dateformat.format(self._period.start, "Y-m-d")
|
||||
|
||||
def has_days_to_choose(self):
|
||||
def has_days_to_choose(self) -> bool:
|
||||
"""Returns whether there are more than one day to choose from.
|
||||
|
||||
Returns:
|
||||
bool: True if there are more than one day to choose from,
|
||||
or False otherwise.
|
||||
True if there are more than one day to choose from, or False
|
||||
otherwise.
|
||||
"""
|
||||
if self._data_start is None:
|
||||
return False
|
||||
@ -313,33 +316,35 @@ class Period:
|
||||
return False
|
||||
return True
|
||||
|
||||
def first_day(self):
|
||||
def first_day(self) -> Optional[str]:
|
||||
"""Returns the specification of the available first day.
|
||||
|
||||
Returns:
|
||||
str: The specification of the available first day.
|
||||
The specification of the available first day, or None if there is
|
||||
no data.
|
||||
"""
|
||||
if self._data_start is None:
|
||||
return None
|
||||
return dateformat.format(self._data_start, "Y-m-d")
|
||||
|
||||
def last_day(self):
|
||||
def last_day(self) -> Optional[str]:
|
||||
"""Returns the specification of the available last day.
|
||||
|
||||
Returns:
|
||||
str: The specification of the available last day.
|
||||
The specification of the available last day, or None if there is no
|
||||
data.
|
||||
"""
|
||||
if self._data_end is None:
|
||||
return None
|
||||
return dateformat.format(self._data_end, "Y-m-d")
|
||||
|
||||
def chosen_start(self):
|
||||
def chosen_start(self) -> Optional[str]:
|
||||
"""Returns the specification of of the first day of the
|
||||
specified period.
|
||||
|
||||
Returns:
|
||||
str: The specification of of the first day of the
|
||||
specified period.
|
||||
The specification of of the first day of the specified period, or
|
||||
None if there is no data.
|
||||
"""
|
||||
if self._data_start is None:
|
||||
return None
|
||||
@ -348,13 +353,13 @@ class Period:
|
||||
else self._data_start
|
||||
return dateformat.format(day, "Y-m-d")
|
||||
|
||||
def chosen_end(self):
|
||||
def chosen_end(self) -> Optional[str]:
|
||||
"""Returns the specification of of the last day of the
|
||||
specified period.
|
||||
|
||||
Returns:
|
||||
str: The specification of of the last day of the
|
||||
specified period.
|
||||
The specification of of the last day of the specified period, or
|
||||
None if there is data.
|
||||
"""
|
||||
if self._data_end is None:
|
||||
return None
|
||||
@ -363,12 +368,12 @@ class Period:
|
||||
else self._data_end
|
||||
return dateformat.format(day, "Y-m-d")
|
||||
|
||||
def period_before(self):
|
||||
def period_before(self) -> Optional[str]:
|
||||
"""Returns the specification of the period before the current period.
|
||||
|
||||
Returns:
|
||||
str|None: The specification of the period before the current
|
||||
period, or None if there is no data before the current period.
|
||||
The specification of the period before the current period, or None
|
||||
if there is no data before the current period.
|
||||
"""
|
||||
if self._data_start is None:
|
||||
return None
|
||||
@ -381,11 +386,12 @@ class Period:
|
||||
return dateformat.format(previous_day, "-Y-m")
|
||||
return dateformat.format(previous_day, "-Y-m-d")
|
||||
|
||||
def month_picker_params(self):
|
||||
def month_picker_params(self) -> Optional[str]:
|
||||
"""Returns the parameters for the month-picker, as a JSON text string.
|
||||
|
||||
Returns:
|
||||
str: The parameters for the month-picker, as a JSON text string.
|
||||
The parameters for the month-picker, as a JSON text string, or None
|
||||
if there is no data.
|
||||
"""
|
||||
if self._data_start is None:
|
||||
return None
|
||||
@ -398,7 +404,7 @@ class Period:
|
||||
})
|
||||
|
||||
@staticmethod
|
||||
def default_spec():
|
||||
def default_spec() -> str:
|
||||
"""Returns the specification for the default period.
|
||||
|
||||
Returns:
|
||||
@ -422,9 +428,9 @@ class Period:
|
||||
description (str): The text description of the period.
|
||||
prep_desc (str): The text description with preposition.
|
||||
"""
|
||||
VERY_START = datetime.date(1990, 1, 1)
|
||||
VERY_START: datetime.date = datetime.date(1990, 1, 1)
|
||||
|
||||
def __init__(self, spec):
|
||||
def __init__(self, spec: str):
|
||||
self.spec = None
|
||||
self.start = None
|
||||
self.end = None
|
||||
@ -574,7 +580,7 @@ class Period:
|
||||
# Wrong period format
|
||||
raise ValueError
|
||||
|
||||
def _set_this_month(self):
|
||||
def _set_this_month(self) -> None:
|
||||
"""Sets the period to this month."""
|
||||
today = timezone.localdate()
|
||||
self.spec = dateformat.format(today, "Y-m")
|
||||
@ -583,14 +589,14 @@ class Period:
|
||||
self.description = gettext("This Month")
|
||||
|
||||
@staticmethod
|
||||
def _month_last_day(day):
|
||||
def _month_last_day(day: datetime.date) -> datetime.date:
|
||||
"""Calculates and returns the last day of a month.
|
||||
|
||||
Args:
|
||||
day (datetime.date): A day in the month.
|
||||
day: A day in the month.
|
||||
|
||||
Returns:
|
||||
date: The last day in the month
|
||||
The last day in the month
|
||||
"""
|
||||
next_month = day.month + 1
|
||||
next_year = day.year
|
||||
@ -601,15 +607,15 @@ class Period:
|
||||
next_year, next_month, 1) - datetime.timedelta(days=1)
|
||||
|
||||
@staticmethod
|
||||
def _month_text(year, month):
|
||||
def _month_text(year: int, month: int) -> str:
|
||||
"""Returns the text description of a month.
|
||||
|
||||
Args:
|
||||
year (int): The year.
|
||||
month (int): The month.
|
||||
year: The year.
|
||||
month: The month.
|
||||
|
||||
Returns:
|
||||
str: The description of the month.
|
||||
The description of the month.
|
||||
"""
|
||||
today = timezone.localdate()
|
||||
if year == today.year and month == today.month:
|
||||
@ -625,14 +631,14 @@ class Period:
|
||||
return "%d/%d" % (year, month)
|
||||
|
||||
@staticmethod
|
||||
def _year_text(year):
|
||||
def _year_text(year: int) -> str:
|
||||
"""Returns the text description of a year.
|
||||
|
||||
Args:
|
||||
year (int): The year.
|
||||
year: The year.
|
||||
|
||||
Returns:
|
||||
str: The description of the year.
|
||||
The description of the year.
|
||||
"""
|
||||
this_year = timezone.localdate().year
|
||||
if year == this_year:
|
||||
@ -642,14 +648,14 @@ class Period:
|
||||
return str(year)
|
||||
|
||||
@staticmethod
|
||||
def _date_text(day):
|
||||
def _date_text(day: datetime.date) -> str:
|
||||
"""Returns the text description of a day.
|
||||
|
||||
Args:
|
||||
day (datetime.date): The date.
|
||||
day: The date.
|
||||
|
||||
Returns:
|
||||
str: The description of the day.
|
||||
The description of the day.
|
||||
"""
|
||||
today = timezone.localdate()
|
||||
if day == today:
|
||||
|
@ -19,16 +19,18 @@
|
||||
|
||||
"""
|
||||
import random
|
||||
from typing import Dict, Mapping, Any, Optional
|
||||
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.http import HttpResponseRedirect, HttpRequest
|
||||
from django.shortcuts import redirect
|
||||
|
||||
from .utils import UrlBuilder
|
||||
|
||||
STORAGE_KEY = "stored_post"
|
||||
STORAGE_KEY: str = "stored_post"
|
||||
|
||||
|
||||
def error_redirect(request, url, post):
|
||||
def error_redirect(request: HttpRequest, url: str,
|
||||
post: Dict[str, str]) -> HttpResponseRedirect:
|
||||
"""Redirects to a specific URL on error, with the POST data ID appended
|
||||
as the query parameter "s". The POST data can be loaded with the
|
||||
get_previous_post() utility.
|
||||
@ -45,7 +47,7 @@ def error_redirect(request, url, post):
|
||||
return redirect(str(UrlBuilder(url).query(s=post_id)))
|
||||
|
||||
|
||||
def get_previous_post(request):
|
||||
def get_previous_post(request: HttpRequest) -> Optional[Dict[str, str]]:
|
||||
"""Retrieves the previously-stored POST data.
|
||||
|
||||
Args:
|
||||
@ -59,16 +61,16 @@ def get_previous_post(request):
|
||||
return _retrieve(request, request.GET["s"])
|
||||
|
||||
|
||||
def _store(request, post):
|
||||
def _store(request: HttpRequest, post: Dict[str, str]) -> str:
|
||||
"""Stores the POST data into the session, and returns the POST data ID that
|
||||
can be used to retrieve it later with _retrieve().
|
||||
|
||||
Args:
|
||||
request (HttpRequest): The request.
|
||||
post (dict): The POST data.
|
||||
request: The request.
|
||||
post: The POST data.
|
||||
|
||||
Returns:
|
||||
str: The POST data ID
|
||||
The POST data ID
|
||||
"""
|
||||
if STORAGE_KEY not in request.session:
|
||||
request.session[STORAGE_KEY] = {}
|
||||
@ -77,15 +79,15 @@ def _store(request, post):
|
||||
return post_id
|
||||
|
||||
|
||||
def _retrieve(request, post_id):
|
||||
def _retrieve(request: HttpRequest, post_id: str) -> Optional[Dict[str, str]]:
|
||||
"""Retrieves the POST data from the storage.
|
||||
|
||||
Args:
|
||||
request (HttpRequest): The request.
|
||||
post_id (str): The POST data ID.
|
||||
request: The request.
|
||||
post_id: The POST data ID.
|
||||
|
||||
Returns:
|
||||
dict: The POST data, or None if the corresponding data does not exist.
|
||||
The POST data, or None if the corresponding data does not exist.
|
||||
"""
|
||||
if STORAGE_KEY not in request.session:
|
||||
return None
|
||||
@ -94,7 +96,7 @@ def _retrieve(request, post_id):
|
||||
return request.session[STORAGE_KEY][post_id]
|
||||
|
||||
|
||||
def _new_post_id(post_store):
|
||||
def _new_post_id(post_store: Mapping[int, Any]) -> str:
|
||||
"""Generates and returns a new POST ID that does not exist yet.
|
||||
|
||||
Args:
|
||||
|
@ -18,12 +18,14 @@
|
||||
"""The template tags and filters of the Mia core application.
|
||||
|
||||
"""
|
||||
import datetime
|
||||
from datetime import date
|
||||
from typing import Any
|
||||
|
||||
import titlecase
|
||||
from django import template
|
||||
from django.http import HttpRequest
|
||||
from django.template import defaultfilters
|
||||
from django.template import defaultfilters, RequestContext
|
||||
from django.urls import reverse
|
||||
from django.utils import timezone
|
||||
from django.utils.safestring import SafeString
|
||||
@ -35,31 +37,31 @@ register = template.Library()
|
||||
|
||||
|
||||
@register.simple_tag(takes_context=True)
|
||||
def setvar(context, key, value):
|
||||
def setvar(context: RequestContext, key: str, value: Any) -> str:
|
||||
"""Sets a variable in the template.
|
||||
|
||||
Args:
|
||||
context (Context): the context
|
||||
key (str): The variable name
|
||||
value (str): The variable value
|
||||
context: the context
|
||||
key: The variable name
|
||||
value: The variable value
|
||||
|
||||
Returns:
|
||||
str: An empty string.
|
||||
An empty string.
|
||||
"""
|
||||
context.dicts[0][key] = value
|
||||
return ""
|
||||
|
||||
|
||||
@register.simple_tag(takes_context=True)
|
||||
def url_period(context, period_spec):
|
||||
def url_period(context: RequestContext, period_spec: str) -> str:
|
||||
"""Returns the current URL with a new period.
|
||||
|
||||
Args:
|
||||
context (RequestContext): The request context.
|
||||
period_spec (str): The period specification.
|
||||
context: The request context.
|
||||
period_spec: The period specification.
|
||||
|
||||
Returns:
|
||||
str: The current URL with the new period.
|
||||
The current URL with the new period.
|
||||
"""
|
||||
view_name = "%s:%s" % (
|
||||
context.request.resolver_match.app_name,
|
||||
@ -70,47 +72,47 @@ def url_period(context, period_spec):
|
||||
|
||||
|
||||
@register.simple_tag(takes_context=True)
|
||||
def url_with_return(context, url):
|
||||
def url_with_return(context: RequestContext, url: str) -> str:
|
||||
"""Returns the URL with the current page added as the "r" query parameter,
|
||||
so that returning to this page is possible.
|
||||
|
||||
Args:
|
||||
context (RequestContext): The request context.
|
||||
url (str): The URL.
|
||||
context: The request context.
|
||||
url: The URL.
|
||||
|
||||
Returns:
|
||||
str: The URL with the current page added as the "r" query parameter.
|
||||
The URL with the current page added as the "r" query parameter.
|
||||
"""
|
||||
return str(UrlBuilder(url).query(
|
||||
r=str(UrlBuilder(context.request.get_full_path()).remove("s"))))
|
||||
|
||||
|
||||
@register.simple_tag(takes_context=True)
|
||||
def url_keep_return(context, url):
|
||||
def url_keep_return(context: RequestContext, url: str) -> str:
|
||||
"""Returns the URL with the current "r" query parameter set, so that the
|
||||
next processor can still return to the same page.
|
||||
|
||||
Args:
|
||||
context (RequestContext): The request context.
|
||||
url (str): The URL.
|
||||
context: The request context.
|
||||
url: The URL.
|
||||
|
||||
Returns:
|
||||
str: The URL with the current "r" query parameter set.
|
||||
The URL with the current "r" query parameter set.
|
||||
"""
|
||||
return str(UrlBuilder(url).query(r=context.request.GET.get("r")))
|
||||
|
||||
|
||||
@register.simple_tag(takes_context=True)
|
||||
def add_css(context, url):
|
||||
def add_css(context: RequestContext, url: str) -> str:
|
||||
"""Adds a local CSS file. The file is added to the "css" template
|
||||
list variable.
|
||||
|
||||
Args:
|
||||
context (RequestContext): The request context.
|
||||
url (str): The URL or path of the CSS file.
|
||||
context: The request context.
|
||||
url: The URL or path of the CSS file.
|
||||
|
||||
Returns:
|
||||
str: An empty string
|
||||
An empty string
|
||||
"""
|
||||
if "css" not in context.dicts[0]:
|
||||
context.dicts[0]["css"] = []
|
||||
@ -119,16 +121,16 @@ def add_css(context, url):
|
||||
|
||||
|
||||
@register.simple_tag(takes_context=True)
|
||||
def add_js(context, url):
|
||||
def add_js(context: RequestContext, url: str) -> str:
|
||||
"""Adds a local JavaScript file. The file is added to the "js" template
|
||||
list variable.
|
||||
|
||||
Args:
|
||||
context (RequestContext): The request context.
|
||||
url (str): The URL or path of the JavaScript file.
|
||||
context: The request context.
|
||||
url: The URL or path of the JavaScript file.
|
||||
|
||||
Returns:
|
||||
str: An empty string
|
||||
An empty string
|
||||
"""
|
||||
if "js" not in context.dicts[0]:
|
||||
context.dicts[0]["js"] = []
|
||||
@ -137,14 +139,14 @@ def add_js(context, url):
|
||||
|
||||
|
||||
@register.filter
|
||||
def smart_date(value):
|
||||
def smart_date(value: datetime.date) -> str:
|
||||
"""Formats the date for human friendliness.
|
||||
|
||||
Args:
|
||||
value (datetime.date): The date.
|
||||
value: The date.
|
||||
|
||||
Returns:
|
||||
str: The human-friendly format of the date.
|
||||
The human-friendly format of the date.
|
||||
"""
|
||||
if value == date.today():
|
||||
return gettext("Today")
|
||||
@ -156,14 +158,14 @@ def smart_date(value):
|
||||
|
||||
|
||||
@register.filter
|
||||
def smart_month(value):
|
||||
def smart_month(value: datetime.date) -> str:
|
||||
"""Formats the month for human friendliness.
|
||||
|
||||
Args:
|
||||
value (datetime.date): The month.
|
||||
value: The month.
|
||||
|
||||
Returns:
|
||||
str: The human-friendly format of the month.
|
||||
The human-friendly format of the month.
|
||||
"""
|
||||
today = timezone.localdate()
|
||||
if value.year == today.year and value.month == today.month:
|
||||
@ -179,14 +181,14 @@ def smart_month(value):
|
||||
|
||||
|
||||
@register.filter
|
||||
def title_case(value):
|
||||
def title_case(value: str) -> str:
|
||||
"""Formats the title in a proper American-English case.
|
||||
|
||||
Args:
|
||||
value (str): The title.
|
||||
value: The title.
|
||||
|
||||
Returns:
|
||||
str: The title in a proper American-English case.
|
||||
The title in a proper American-English case.
|
||||
"""
|
||||
value = str(value)
|
||||
if isinstance(value, SafeString):
|
||||
@ -195,16 +197,15 @@ def title_case(value):
|
||||
|
||||
|
||||
@register.filter
|
||||
def is_in_section(request, section_name):
|
||||
def is_in_section(request: HttpRequest, section_name: str) -> bool:
|
||||
"""Returns whether the request is currently in a section.
|
||||
|
||||
Args:
|
||||
request (HttpRequest): The request.
|
||||
section_name (str): The view name of this section.
|
||||
request: The request.
|
||||
section_name: The view name of this section.
|
||||
|
||||
Returns:
|
||||
bool: True if the request is currently in this section, or False
|
||||
otherwise
|
||||
True if the request is currently in this section, or False otherwise.
|
||||
"""
|
||||
if request is None:
|
||||
return False
|
||||
|
@ -20,20 +20,22 @@
|
||||
"""
|
||||
import random
|
||||
import urllib.parse
|
||||
from typing import Dict, List, Any, Type
|
||||
|
||||
from django.conf import settings
|
||||
from django.db.models import Model, Q
|
||||
from django.http import HttpRequest
|
||||
from django.utils.translation import pgettext, get_language
|
||||
|
||||
|
||||
def new_pk(cls):
|
||||
def new_pk(cls: Type[Model]) -> int:
|
||||
"""Finds a random ID that does not conflict with the existing data records.
|
||||
|
||||
Args:
|
||||
cls (class): The Django model class.
|
||||
cls: The Django model class.
|
||||
|
||||
Returns:
|
||||
int: The new random ID.
|
||||
The new random ID.
|
||||
"""
|
||||
while True:
|
||||
pk = random.randint(100000000, 999999999)
|
||||
@ -43,7 +45,7 @@ def new_pk(cls):
|
||||
return pk
|
||||
|
||||
|
||||
def strip_post(post):
|
||||
def strip_post(post: Dict[str, str]) -> None:
|
||||
"""Strips the values of the POSTed data. Empty strings are removed.
|
||||
|
||||
Args:
|
||||
@ -59,7 +61,7 @@ class Language:
|
||||
"""A language.
|
||||
|
||||
Args:
|
||||
language (str): The Django language code.
|
||||
language: The Django language code.
|
||||
|
||||
Attributes:
|
||||
id (str): The language ID
|
||||
@ -67,7 +69,7 @@ class Language:
|
||||
locale (str); The locale name of this language.
|
||||
is_default (bool): Whether this is the default language.
|
||||
"""
|
||||
def __init__(self, language):
|
||||
def __init__(self, language: str):
|
||||
self.id = language
|
||||
self.db = "_" + language.lower().replace("-", "_")
|
||||
if language == "zh-hant":
|
||||
@ -87,17 +89,18 @@ class Language:
|
||||
return Language(get_language())
|
||||
|
||||
|
||||
def get_multi_lingual_attr(model, name, default=None):
|
||||
def get_multi_lingual_attr(model: Model, name: str,
|
||||
default: str = None) -> str:
|
||||
"""Returns a multi-lingual attribute of a data model.
|
||||
|
||||
Args:
|
||||
model (object): The data model.
|
||||
name (str): The attribute name.
|
||||
default (str): The default language.
|
||||
model: The data model.
|
||||
name: The attribute name.
|
||||
default: The default language.
|
||||
|
||||
Returns:
|
||||
(any): The attribute in this language, or in the default
|
||||
language if there is no content in the current language.
|
||||
The attribute in this language, or in the default language if there is
|
||||
no content in the current language.
|
||||
"""
|
||||
language = Language.current()
|
||||
title = getattr(model, name + language.db)
|
||||
@ -110,27 +113,27 @@ def get_multi_lingual_attr(model, name, default=None):
|
||||
return getattr(model, name + Language.default().db)
|
||||
|
||||
|
||||
def set_multi_lingual_attr(model, name, value):
|
||||
def set_multi_lingual_attr(model: Model, name: str, value: str) -> None:
|
||||
"""Sets a multi-lingual attribute of a data model.
|
||||
|
||||
Args:
|
||||
model (object): The data model.
|
||||
name (str): The attribute name.
|
||||
value (any): The new value
|
||||
model: The data model.
|
||||
name: The attribute name.
|
||||
value: The new value
|
||||
"""
|
||||
language = Language.current()
|
||||
setattr(model, name + language.db, value)
|
||||
|
||||
|
||||
def get_multi_lingual_search(attr, query):
|
||||
def get_multi_lingual_search(attr: str, query: str) -> Q:
|
||||
"""Returns the query condition on a multi-lingual attribute.
|
||||
|
||||
Args:
|
||||
attr (str): The base name of the multi-lingual attribute.
|
||||
query (str): The query.
|
||||
attr: The base name of the multi-lingual attribute.
|
||||
query: The query.
|
||||
|
||||
Returns:
|
||||
Q: The query condition
|
||||
The query condition
|
||||
"""
|
||||
language = Language.current()
|
||||
if language.is_default:
|
||||
@ -147,10 +150,10 @@ class UrlBuilder:
|
||||
"""The URL builder.
|
||||
|
||||
Attributes:
|
||||
base_path (str): the base path
|
||||
path (str): the base path
|
||||
params (list[Param]): The query parameters
|
||||
"""
|
||||
def __init__(self, start_url):
|
||||
def __init__(self, start_url: str):
|
||||
"""Constructs a new URL builder.
|
||||
|
||||
Args:
|
||||
@ -158,10 +161,10 @@ class UrlBuilder:
|
||||
"""
|
||||
pos = start_url.find("?")
|
||||
if pos == -1:
|
||||
self.base_path = start_url
|
||||
self.path = start_url
|
||||
self.params = []
|
||||
return
|
||||
self.base_path = start_url[:pos]
|
||||
self.path = start_url[:pos]
|
||||
self.params = []
|
||||
for piece in start_url[pos + 1:].split("&"):
|
||||
pos = piece.find("=")
|
||||
@ -219,25 +222,25 @@ class UrlBuilder:
|
||||
Returns:
|
||||
UrlBuilder: A copy of this URL builder.
|
||||
"""
|
||||
another = UrlBuilder(self.base_path)
|
||||
another = UrlBuilder(self.path)
|
||||
another.params = [
|
||||
self.Param(x.name, x.value) for x in self.params]
|
||||
return another
|
||||
|
||||
def __str__(self):
|
||||
def __str__(self) -> str:
|
||||
if len(self.params) == 0:
|
||||
return self.base_path
|
||||
return self.base_path + "?" + "&".join([
|
||||
return self.path
|
||||
return self.path + "?" + "&".join([
|
||||
str(x) for x in self.params])
|
||||
|
||||
class Param:
|
||||
"""A query parameter.
|
||||
|
||||
Attributes:
|
||||
name (str): The parameter name
|
||||
value (str): The parameter value
|
||||
name: The parameter name
|
||||
value: The parameter value
|
||||
"""
|
||||
def __init__(self, name, value):
|
||||
def __init__(self, name: str, value: str):
|
||||
"""Constructs a new query parameter
|
||||
|
||||
Args:
|
||||
@ -247,7 +250,7 @@ class UrlBuilder:
|
||||
self.name = name
|
||||
self.value = value
|
||||
|
||||
def __str__(self):
|
||||
def __str__(self) -> str:
|
||||
"""Returns the string representation of this query
|
||||
parameter.
|
||||
|
||||
@ -264,9 +267,9 @@ class Pagination:
|
||||
"""The pagination.
|
||||
|
||||
Args:
|
||||
request (HttpRequest): The request.
|
||||
items (list): All the items.
|
||||
is_reversed (bool): Whether we should display the last page first.
|
||||
request: The request.
|
||||
items: All the items.
|
||||
is_reversed: Whether we should display the last page first.
|
||||
|
||||
Raises:
|
||||
PaginationException: With invalid pagination parameters
|
||||
@ -282,7 +285,8 @@ class Pagination:
|
||||
"""
|
||||
DEFAULT_PAGE_SIZE = 10
|
||||
|
||||
def __init__(self, request, items, is_reversed=False):
|
||||
def __init__(self, request: HttpRequest, items: List[Any],
|
||||
is_reversed: bool = False):
|
||||
self.current_url = UrlBuilder(request.get_full_path())
|
||||
self.is_reversed = is_reversed
|
||||
self.page_size = self.DEFAULT_PAGE_SIZE
|
||||
@ -334,7 +338,7 @@ class Pagination:
|
||||
"""Returns the navigation links of the pagination bar.
|
||||
|
||||
Returns:
|
||||
list[Link]: The navigation links of the pagination bar.
|
||||
List[Link]: The navigation links of the pagination bar.
|
||||
"""
|
||||
base_url = self.current_url.clone().remove("page").remove("s")
|
||||
links = []
|
||||
@ -443,14 +447,14 @@ class Pagination:
|
||||
"""Returns the page size options.
|
||||
|
||||
Returns:
|
||||
list[PageSizeOption]: The page size options.
|
||||
List[PageSizeOption]: The page size options.
|
||||
"""
|
||||
base_url = self.current_url.remove("page").remove("page-size")
|
||||
return [self.PageSizeOption(x, self._page_size_url(base_url, x))
|
||||
for x in [10, 100, 200]]
|
||||
|
||||
@staticmethod
|
||||
def _page_size_url(base_url, size):
|
||||
def _page_size_url(base_url: UrlBuilder, size: int) -> str:
|
||||
"""Returns the URL for a new page size.
|
||||
|
||||
Args:
|
||||
@ -468,14 +472,14 @@ class Pagination:
|
||||
"""A page size option.
|
||||
|
||||
Args:
|
||||
size (int): The page size.
|
||||
url (str): The URL of this page size.
|
||||
size: The page size.
|
||||
url: The URL of this page size.
|
||||
|
||||
Attributes:
|
||||
size (int): The page size.
|
||||
url (str): The URL for this page size.
|
||||
"""
|
||||
def __init__(self, size, url):
|
||||
def __init__(self, size: int, url: str):
|
||||
self.size = size
|
||||
self.url = url
|
||||
|
||||
@ -484,10 +488,10 @@ class PaginationException(Exception):
|
||||
"""The exception thrown with invalid pagination parameters.
|
||||
|
||||
Args:
|
||||
url_builder (UrlBuilder): The canonical URL to redirect to.
|
||||
url_builder: The canonical URL to redirect to.
|
||||
|
||||
Attributes:
|
||||
url (str): The canonical URL to redirect to.
|
||||
"""
|
||||
def __init__(self, url_builder):
|
||||
def __init__(self, url_builder: UrlBuilder):
|
||||
self.url = str(url_builder)
|
||||
|
@ -21,7 +21,8 @@
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth import logout as logout_user
|
||||
from django.contrib.messages.views import SuccessMessageMixin
|
||||
from django.http import HttpResponse, JsonResponse
|
||||
from django.http import HttpResponse, JsonResponse, HttpRequest, \
|
||||
HttpResponseRedirect
|
||||
from django.shortcuts import redirect, render
|
||||
from django.urls import reverse
|
||||
from django.utils.decorators import method_decorator
|
||||
@ -47,14 +48,14 @@ class DeleteView(SuccessMessageMixin, CoreDeleteView):
|
||||
|
||||
|
||||
@require_POST
|
||||
def logout(request):
|
||||
def logout(request: HttpRequest) -> HttpResponseRedirect:
|
||||
"""The view to log out a user.
|
||||
|
||||
Args:
|
||||
request (HttpRequest): The request.
|
||||
request: The request.
|
||||
|
||||
Returns:
|
||||
HttpRedirectResponse: The redirect response.
|
||||
The redirect response.
|
||||
"""
|
||||
logout_user(request)
|
||||
if "next" in request.POST:
|
||||
@ -80,15 +81,15 @@ class UserView(DetailView):
|
||||
|
||||
@require_GET
|
||||
@login_required
|
||||
def user_form(request, user=None):
|
||||
def user_form(request: HttpRequest, user: User = None) -> HttpResponse:
|
||||
"""The view to edit an accounting transaction.
|
||||
|
||||
Args:
|
||||
request (HttpRequest): The request.
|
||||
user (User): The account.
|
||||
request: The request.
|
||||
user: The account.
|
||||
|
||||
Returns:
|
||||
HttpResponse: The response.
|
||||
The response.
|
||||
"""
|
||||
previous_post = stored_post.get_previous_post(request)
|
||||
if previous_post is not None:
|
||||
@ -108,15 +109,16 @@ def user_form(request, user=None):
|
||||
})
|
||||
|
||||
|
||||
def user_store(request, user=None):
|
||||
def user_store(request: HttpRequest,
|
||||
user: User = None) -> HttpResponseRedirect:
|
||||
"""The view to store a user.
|
||||
|
||||
Args:
|
||||
request (HttpRequest): The request.
|
||||
user (Account): The user.
|
||||
request: The request.
|
||||
user: The user.
|
||||
|
||||
Returns:
|
||||
HttpResponseRedirect: The response.
|
||||
The response.
|
||||
"""
|
||||
post = request.POST.dict()
|
||||
strip_post(post)
|
||||
@ -148,15 +150,15 @@ def user_store(request, user=None):
|
||||
|
||||
@require_POST
|
||||
@login_required
|
||||
def user_delete(request, user):
|
||||
def user_delete(request: HttpRequest, user: User) -> HttpResponseRedirect:
|
||||
"""The view to delete an user.
|
||||
|
||||
Args:
|
||||
request (HttpRequest): The request.
|
||||
user (User): The user.
|
||||
request: The request.
|
||||
user: The user.
|
||||
|
||||
Returns:
|
||||
HttpResponseRedirect: The response.
|
||||
The response.
|
||||
"""
|
||||
message = None
|
||||
if user.pk == request.user.pk:
|
||||
@ -177,14 +179,14 @@ def user_delete(request, user):
|
||||
|
||||
@require_GET
|
||||
@login_required
|
||||
def my_account_form(request):
|
||||
def my_account_form(request: HttpRequest) -> HttpResponse:
|
||||
"""The view to edit my account.
|
||||
|
||||
Args:
|
||||
request (HttpRequest): The request.
|
||||
request: The request.
|
||||
|
||||
Returns:
|
||||
HttpResponse: The response.
|
||||
The response.
|
||||
"""
|
||||
previous_post = stored_post.get_previous_post(request)
|
||||
if previous_post is not None:
|
||||
@ -201,14 +203,14 @@ def my_account_form(request):
|
||||
})
|
||||
|
||||
|
||||
def my_account_store(request):
|
||||
def my_account_store(request: HttpRequest) -> HttpResponseRedirect:
|
||||
"""The view to store my account.
|
||||
|
||||
Args:
|
||||
request (HttpRequest): The request.
|
||||
request: The request.
|
||||
|
||||
Returns:
|
||||
HttpResponseRedirect: The response.
|
||||
The response.
|
||||
"""
|
||||
post = request.POST.dict()
|
||||
strip_post(post)
|
||||
@ -232,15 +234,15 @@ def my_account_store(request):
|
||||
return redirect("mia_core:my-account")
|
||||
|
||||
|
||||
def api_users_exists(request, login_id):
|
||||
def api_users_exists(request: HttpRequest, login_id: str) -> JsonResponse:
|
||||
"""The view to check whether a user with a log in ID exists.
|
||||
|
||||
Args:
|
||||
request (HttpRequest): The request.
|
||||
login_id (str): The log in ID.
|
||||
request: The request.
|
||||
login_id: The log in ID.
|
||||
|
||||
Returns:
|
||||
JsonResponse: The response.
|
||||
The response.
|
||||
"""
|
||||
try:
|
||||
User.objects.get(login_id=login_id)
|
||||
|
Loading…
Reference in New Issue
Block a user