Обновлен список городов - теперь он не в базе данных, а в статических объектах. Обновлена работа с медиа - теперь их можно полноценно загружать и скачивать с сервера.

This commit is contained in:
2023-03-28 14:10:28 +03:00
parent d4158ae1c0
commit a9d3a34c0b
8 changed files with 207 additions and 86 deletions

View File

@@ -8,39 +8,11 @@ from hashlib import sha512, sha256
from django.db.models import Q
from django.db.utils import ProgrammingError
from arka.settings import CITIES_CHOICES, CITIES_FIELD_SIZE
from .api_errors import *
import re
class City(models.Model):
code = models.CharField(primary_key=True, max_length=20, verbose_name="Код города", validators=[
RegexValidator(regex="^[0-9a-zA-Z_]*$"),
])
name = models.CharField(unique=True, max_length=50, verbose_name="Название города")
def __str__(self):
return f"{self.name} ({self.code})"
@staticmethod
async def to_choices_async():
return [item async for item in City.objects.order_by('name').values_list('code', 'name')]
@staticmethod
def to_choices():
try:
return list(City.objects.order_by('name').values_list('code', 'name'))
except ProgrammingError:
return []
@staticmethod
async def get_by_code(code):
if code is None:
return None
return await City.objects.aget(code=code)
class Account(models.Model):
surname = models.CharField(max_length=60, verbose_name="Фамилия", blank=True, default="")
name = models.CharField(max_length=60, verbose_name="Имя", blank=True, default="")
@@ -65,7 +37,7 @@ class Account(models.Model):
about = models.CharField(max_length=1000, blank=True, default="", verbose_name="О себе")
city = models.ForeignKey(City, on_delete=models.SET_NULL, default=None, null=True, blank=True)
city = models.CharField(max_length=CITIES_FIELD_SIZE, choices=CITIES_CHOICES, default=None, null=True, blank=True)
register_datetime = models.DateTimeField(default=datetime.now, editable=False)
@@ -94,7 +66,7 @@ class Account(models.Model):
raise Exception(API_ERROR_NOT_FOUND, "user")
async def get_by_id(self, user_id: int):
u = Account.objects.filter(id=user_id).select_related('executoraccount', 'city')
u = Account.objects.filter(id=user_id).select_related('executoraccount', 'accountavatar')
if self.role == Account.ROLE_EXECUTOR or self.role == Account.ROLE_CUSTOMER:
u.filter(role__in=[Account.ROLE_EXECUTOR, Account.ROLE_CUSTOMER])
@@ -117,13 +89,16 @@ class Account(models.Model):
return f"{self.name} {self.surname}: {self.phone} ({r})"
def is_completed(self):
return self.name != '' and self.surname != '' and self.city_id is not None
return self.name != '' and self.surname != '' and self.city is not None
class Media(models.Model):
user = models.ForeignKey(Account, on_delete=models.SET_NULL, null=True)
storage_name = models.CharField(max_length=100, verbose_name="Файл в хранилище")
owner = models.ForeignKey(Account, on_delete=models.SET_NULL, null=True,
related_name="media_owner", verbose_name="Владелец")
storage_name = models.CharField(max_length=80, verbose_name="Файл в хранилище")
original_name = models.CharField(max_length=100, verbose_name="Имя файла", default="")
extension = models.CharField(max_length=16)
size = models.IntegerField(verbose_name='Размер в байтах')
upload_datetime = models.DateTimeField(default=datetime.now, editable=False)
@staticmethod
@@ -135,13 +110,21 @@ class Media(models.Model):
async def get_media():
pass
def generate_storage_name(self):
if self.storage_name is None:
source_str = f"{self.original_name} {self.original_name} {self.upload_datetime} {self.user.id}"
self.storage_name = sha512(bytearray(source_str, 'utf-8')).hexdigest()
@staticmethod
def generate_storage_name(original_name, upload_datetime, user_id):
source_str = f"{original_name} {upload_datetime} {user_id}"
return sha256(bytearray(source_str, 'utf-8')).hexdigest()
def __str__(self):
return f"{self.user}: \"{self.original_name}\" ({self.id})"
return f"{self.owner}: \"{self.original_name}\" ({self.id})"
class AccountAvatar(models.Model):
account = models.OneToOneField(Account, on_delete=models.CASCADE, related_name="account", verbose_name="Аккаунт")
photo = models.ForeignKey(Media, on_delete=models.SET_NULL, null=True,
related_name="photo", verbose_name="Аватар")
profile_background = models.ForeignKey(Media, on_delete=models.SET_NULL, null=True, default=None,
related_name="profile_background", verbose_name="Оформление профиля")
def _executor_additional_info_default():
@@ -205,12 +188,12 @@ class AccessToken(models.Model):
@staticmethod
async def get_user_by_token(token: str):
return (await AccessToken.get_by_token(token)).user
return (await AccessToken.get_by_token(token)).owner
@staticmethod
async def get_by_token(token: str):
t = await AccessToken.objects.filter(access_token=token)\
.select_related('user', 'user__executoraccount', 'user__city').afirst()
t = await AccessToken.objects.filter(access_token=token).select_related('user',
'user__executoraccount').afirst()
if t is None:
raise Exception(API_ERROR_INVALID_TOKEN)
return t
@@ -342,8 +325,8 @@ class Order(models.Model):
date_start = models.DateField(null=True, blank=True, default=None, verbose_name="Дата начала")
date_end = models.DateField(null=True, blank=True, default=None, verbose_name="Дата окончания")
address_city = models.ForeignKey(City, on_delete=models.CASCADE, blank=False, related_name="address_city",
verbose_name="Город")
address_city = models.CharField(max_length=CITIES_FIELD_SIZE, choices=CITIES_CHOICES,
blank=False, verbose_name="Город")
address_text = models.CharField(max_length=70, blank=True, verbose_name="Улица, дом")
owner = models.ForeignKey(Account, on_delete=models.CASCADE, related_name="owner", verbose_name="Владелец")
@@ -377,7 +360,6 @@ class Order(models.Model):
return q[0]
# def _upload_image_filename(instance, filename):
# name, ext = os.path.splitext(filename)
# fn = sha256((str(datetime.now()) + name).encode('utf-8')).hexdigest() + ext
@@ -428,4 +410,3 @@ class Order(models.Model):
# self.full_clean()
#
# super().save(*args, **kwargs)