Комментарии 15
представление redirect можно и нужно сделать через views.generic.RedirectView добавив SingleObjectMixin.
переопределять save модели - такое себе решение. Не запрещено, конечно, но чисткой данных (генерацией short) дожен бы заниматься serializer/форма.
blank=True # поле short_url может быть пустым, предполагается, что наш сервис будет сам генерить короткие ссылки.
не понял, как связано то, что в формах поле ввода будет не обязательное (required=False) с генерацией ссылок.
Для надежности я бы использовал Token.pk как короткую ссылку. Его всегда можно в символы превратить. Кстати, название модели, рекомендуется сделать Token, единственное число.
На работу взяли?
token.requests_count += 1 # добавляем 1 к счетчику в случае удачного извлечения токена
token.save() # сохраняем изменный экземпляр токена в БД
Я не особо хорош в django, но в нашем тесте про url shortener это было сигналом того, что человек не знает что бывают race conditions. Попробуйте сделать 1000 запросов с concurrency 5 с помощью siege и посмотреть результат. Что-то мне подсказывает, что это будет не 1000
Привет!
Пару советов для дальнейшего успешного поиска работы:
Используй сразу python poetry + Dockerfile + docker-compose. Сейчас это такие же стандарты, как знание git. Дадут тебе +15 очков на собеседовании.
class Tokens(models.Model)
->class Token(models.Model)
settings.CHARACTERS = string.ascii_letters + string.ascii_digits
+5 очковВместо цикла
while True с filter() query
надо использоватьtry: Model.objects.create() / except IntegrityError
- так будет в 99.9% случаев только один запрос. +30 очковtoken.requests_count += 1
->Models.objects.filter().update(requests_count=F("requests_count")+1)
+20 очковВынести код из
save()
в отдельный модульservices.create_token
. +15 очковМожно вместо рандомайзера использовать hash от pk, но это так уже, когда совсем делать нечего :) Нашел в одном из своих старых проектов:
hashlib.shake_128(user_id.encode("utf-8")).hexdigest(3).upper()
ну, если говорим про django тогда уж:
Очень субъективно. Я, как наниматель, а я наниматель, скорее поморщусь, чем порадуюсь появлению доп зависимостей в проекте.
settings.CHARACTERS = django.utils.baseconv.BASE62_ALPHABET
или
settings.CHARACTERS = django.utils.crypto.RANDOM_STRING_CHARS
4.-5. Вместо этого всего использовать метод Data Manager, точнее порожденной им производной класса queryset.
Services и прочие заблуждения гексагональной архитектуры. Очень спорно для Django. По мне - см п. 4-5
Ох, я был в обоих лагерях "services vs managers". :)
Для больших проектов 100+ моделей обычно выбираю services последнее время. На практике поддерживать service, где и python логика и ORM в одном месте - легче. Да и распиливать потом - одно удовольствие. Но для маленьких проектов, как у автора - согласен, managers предпочтительнее и чище.
В любом случае вердикт один - нужно выносить из save().
Круто! Большое спасибо!
Да, перед отправкой на проверку я все закатал в Dockerfile + docker-compose и развернул в Я.Облаке чтобы сервис работал.
А вот это не до конца понял. Мы же по сути делаем тоже самое, только код становится более громоздским и хуже читается.token.requests_count += 1
-> Models.objects.filter().update(requests_count=F("requests_count")+1)
Пишем сервис для сокращения ссылок на Django, DRF