• Как я из Беларуси в Германию переехал
    +3
    Я из Австрии, мне легко предположить, что на руки в Белоруссии он реально мог получать больше, чем в Aвстрии Netto.
  • Дайджест свежих материалов из мира фронтенда за последнюю неделю №472 (7 — 13 июня 2021)
    0
    Спасибо! Оказывается я пропустил прошлый выпуск. Вот тебе и поклонник :(
  • Сортируем файлы с помощью Python
    0
    Привет. Буквально вчера перебирал file_cache на сервере, папка для временных файлов, которые необходимы пользователям. У нас уже было создано нечто подобное сортировке из статьи. За 6 лет функция обросла многими доработками. Потому расскажу, какие сложности встречались в этой, казалось бы, банальной задаче:

    Предпосылки — 100 гигабайт хранилище, 350 000 файлов, расширения png, gif, ico, jpeg, svg, webp, tiff, pdf, tmp, html, xml, xls, xslx, doc, docx, js, css. Видео ни разу не встречал, хоть и можно. И бесконечное количество файлов с .tmp, .temp или без расширений. Адобовские еще файлы какие то AI, PSD… и т.п.

    Сложности:
    1. Как уже в комментариях сказали — расширение файла не говорит ничего. Хуже того, если отсортировать картинки по расширению, не проверив, для последующей пакетной обработки, например, в PhotoShop или программно в том же PIL — все упадет. Хорошо так упадет.
    Для проверки переимовываем xxxxx.jpg в yyyy.png и открываем в photoshop.

    В итоге мы стали использовать Fleep автор Mykyta Paliienko. Эта утилита сообщает о типе файла по содержимому. Кстати пришлось доработать «fleeper» до рабочего состояния, в issue автору тоже сообщили.

    2. Файлы с именами, написанными через точку, и без расширений. Отдельная задача, поскольку формально расширение есть.

    Решилось так же флиппером.

    В коде git статьи extension получается через fp.split('.')[-1], это аналог os.path.splitext(fp) и оба не помогут в решении пункта 2, но os.path.splitext более «кошерный» в случае работы с файловой системой.

    3. Также в комментариях сказали про однострочные генераторы. Как в статье так и GIT с примером кода, используются листы или функции генераторов, даже там, где достаточно однострочного генератора, который может делать еще и полезную работу:

    # функция def sort_files()
    for fp, (file, extention) in (fp.path, os.path.splitext(fp.path) for fp in os.scandir(folder_path) if not fp.is_dir()):
    ....
    

    Если кого расстраивают длинные строки, например линтер black прям беснуется, то можно так же сделать генераторный pipline:
    # функция def sort_files()
    path_generator = (_file.path for _file in os.scandir(folder_path) if not _file.is_dir())
    extentions_generator = (_path, os.path.splitext(_path) for _path in path_generator)
    for path, (file, extention) in extentions_generator:
    ....
    


    4. Создание папок, и, потом, удаление пустых папок — выглядит вычурно. Если есть словарь хранящий { расширение: путь }, тогда проще получать путь из словаря и создавать путь, если словарь вернул пустое значение.

    5. Логирование. Сложная тема. Более 300 000 сообщений одномоментно в консоль бессмыслены и ломали «terminus»- консоль в sublime text.

    Решение — использовать стандартный логгер Python c выводом в консоль/файл управляя выводом через атрибуты запуска.

    Успехов автору в кодинге.
  • Дайджест свежих материалов из мира фронтенда за последнюю неделю №472 (7 — 13 июня 2021)
    +1
    Привет, alexzfort. Спасибо, продолжаю быть поклонником твоей рубрики.

    Статья «Выкладка нетрадиционной ориентации» это неполный перевод обьемной статьи css-tricks.com/hexagons-and-beyond-flexible-responsive-grid-patterns-sans-media-queries, текст примеры и картинки в переводе взяты оттуда. Хотя основная идея была озвучена крисом койером(Chris Coyier) еще год назад.

    В полной статье есть еще удобный генератор сетки, формы многогранников и расстояний между многогранниками. Про это в переводе забыли, как и не указали о том, что это перевод.
  • Выкладка нетрадиционной ориентации
    +3

    Эээ пометьте что это перевод https://css-tricks.com/hexagons-and-beyond-flexible-responsive-grid-patterns-sans-media-queries/

    Кстати там рассмотрены ещё и сложности в такой вёрстке

  • Создание PDF-документа на Python с помощью pText
    0

    После прочтения у меня сложилось впечатление что это какая то обёртка reportlab-a.

  • Многоразовый шаблон логирования на Python для всех ваших приложений в Data Science
    +1
    привет. Поправьте пожалуйста ошибки — в первом коде для файла logger.py — первая строка
    import logging

    подпись под последней картинкой: Появился лог файл. (log file appears!), а то у вас получается, что должна быть картинка содержимого app_debug.log

    masai — я бы спросил с уточнением: а почему вы переводите текст с медиума, который берет код с docs.python.org/3/howto/logging, а не оригинальную статью?
  • Под капотом у Emoji
    +1

    Спасибо. Очень удобно. Иногда в Ворд файле стоит вместо эмоджи — зачёркнутый квадрат. У меня, например, не виден инфо в кружочке. Если я правильно понял из статьи, то от устройства зависит. Даже интересно, как узнать где это отображается нормально.

  • Дайджест свежих материалов из мира фронтенда за последнюю неделю №458 (8 — 14 марта 2021)
    +1
    raamid, что-то четко определенное ни разу не встречал. Встречу на мой вгляд что дельное, скину в личку. Попробуй спросить у Shpankov, есть на Habr, это тот, кто Vivaldi пилит.
  • Дайджест свежих материалов из мира фронтенда за последнюю неделю №458 (8 — 14 марта 2021)
    +1

    Ага, я ярый читатель этой недельной подборки.
    Немного напрягает, что все что я прочел тремя днями/неделями/месяцами на medium, Dew или где-ещё висит потом в хабр захламляя ленту. Пару недель назад первая страница Хабра выглядела как филиал medium причем с не самым интересным контентом.
    В подборке есть ссылка на логические свойства CSS и на перевод этой статьи. Предлагаю оставить только русский вариант, в нем так и так есть ссылка на английскую версию.

  • HTML ⟹ PDF @ Python
    +1
    Я рад что вспомнили reportlab. В тесте для этой статьи, скорее всего, он стоял бы ниже Html2Pdf с пометкой «очень вредное». Для старта не порекомендую и врагу. А вот потом…

    А вот это потом: Я работаю уже 7 год с reportlab. В 2016 смотрел Html2Pdf, в 2017 смотрел на Weasy, и всегда возвращался обратно. На тот момент reportLab никто не мог переплюнуть по возможностям. Когда-то мне были нужны автосборки индексов и оглавлений, когда-то нестандартная нумерация страниц и печать с пометками линий реза для типографии.

    Сложности:
    Не все шрифты можно было импортировать, пришлось допилить.
    Кернинг не работает нормально. Пришлось разбивать слова на символы и управлять шириной пробела.
    Подчеркивание слов всегда неразрывной линией, не стал менять.
    Падает, если в HTML есть тег span с классом или стилями. Поставил чистилку.

    На текущий момент у нас написано одних только reportLab «улучшалок» на 11 тыс строк. И мне нравится как выглядит конечный продукт, у нас это PDF каталоги продукции.
  • Зачем вам может понадобиться SITE_ID в настройках Django
    0
    xammi-1, сейчас все именно так, думаю, у большинства. И у меня тоже так было.
    Идея, которую не доделали в CurrentSiteManager, в том, что в для IndexView достаточно тогда только указать:
    class IndexView(ListView):
        model = Info
    Остальное должен был бы сделать CurrentSiteManager, если б он правильно работал с рождения. Но увы, пришлось его допилить, но теперь у меня в проектах нет ни одного filter(site=self.request.site)

    Согласен со всеми комментаторами, что:
    сделают это через свои модели, менеджеры и мидлвари
    a от Django у меня остались лишь рожки да ножки названия и идея.
  • Зачем вам может понадобиться SITE_ID в настройках Django
    0
    hellpain а как тогда лучше сделать, если не объявлять objects у класса, чтобы не bad?
  • Конвертеры маршрутов в Django 2.0+ (path converters)
    +3
    по мелочи:
    В самом последнем примере
     queryset = User.objects.all()

    лучше поправить на
    manager = User.objects

    и по месту исправить queryset на manager
    Причина в том, что результат .all() — кешируется и может привести к неожиданным ошибкам.

    Не совсем понятно, почему не через видовые классы решается, кода еще меньше и почему не используется repath для предобработки.

    Но, так или иначе, пример именно с User-репортом не совсем корректный.
    Предположу, что нам нужен лист записей о действии юзера и, что данные об этом хранятся в отдельной модели UserReport.

    Тогда для получения Repor-Листа получать обьект User нам не надо — можно сразу фильтровать по числовому значению user_id. Нет записей — возвращаем «Записей по запрошенному пользователю не найдено».
    Конечно, когда надо делать что-то с самим пользователем, то можно получить связанный объект User, например, одновременно с запросом по UserReport.

    Если придерживаться идеологии джанго, то Resolver должен работать максимально быстро, и, желательно, без запросов в БД: в resolver нет текущего пользователя, который прикреплен в request, и не известно, имеет ли текущий пользователь права доступа к модели обработчика, в примере это модель Users.

    Обработка даты, idsn, EAN — да, это возможно. Как я понимаю в Djangoproject просто отдали на откуп создание частных обработчиков, оставив себе общие случаи: path, slug, string, int, UUID.
  • Удалёнка за доллары: а меня возьмут?
    0

    Если 3000 нетто — при оплате банковскими переводами я оплачиваю: 3000+ налог в той стране куда перевожу с 3000 + 40 транзакция. Я прошу о верной организации выплат типа пенсионного или медицинского страхования. Оплата коворкинга для сотрудника, обучения, конференций — отдельно. Пока у меня 11 сотрудников — австрийцы, немец, россиянин, белорус, украинец.

  • Удалёнка за доллары: а меня возьмут?
    +2
    Хм. Я работодатель из Австрии. И мне не важен ни английский, ни в какой стране разработчик. Договор удаленной работы, или трудоустройство. С переездом или цикличными приездами и удаленкой.
    За время поиска персонала с 2016г я понял несколько моментов:

    Соискатель должен понимать алгоритмы. Вот серьезно. Не получалось у меня общение с людьми, которые не понимают базовых блоков из которых выстраивается программа.

    Соискатель должен иметь желание обогнать меня в профессиональном развитии. Пока речь о django/python/HTML/css. Это и его подстегивает к самообучению и мне не дает застаиваться.

    Стилистика работы соискателя должна вначале хоть как-то но совпадать с принятыми у меня в фирме. Не получилось ни разу «воспитать бабу ягу» если она из другого болота.

    Оплату однозначно устанавливаю в валюте страны где моя фирма — €. Эти плавающие рубли/гривны/кроны портят все желание: у меня платить, когда евро дешевеет, у соискателя работать, когда евро дорожает.

    Самое интересное это ставка. Если я беру кого-то на 3000 евро нетто по трудовому договору — мне такой сотрудник стоит 7500 в месяц. но меньше 2600 нетто тоже не могу взять, если это не EUROпеец, есть нижнее ограничение для приезжих.
    В итоге хочу подправить автора статьи, что все обещания 110 000€ в год — это брутто. Я ни разу не слышал о такой сумме нетто программисту.
    По договору субподряда все проще, плачу меньше, налоги меня не беспокоят, но и риск, что пациент выздоровеет от меня тоже выше.
  • О нет! Моя Data Science ржавеет
    –1
    увидев код, что-то вызвало у меня сомнение в честности результатов.
    import math
    def compute_entropy_pure_python(data):
        """Compute entropy on bytearray `data`."""
        counts = [0] * 256
        entropy = 0.0
        length = len(data)
        for byte in data:
            counts[byte] += 1
        for count in counts:
            if count != 0:
                probability = float(count) / length
                entropy -= probability * math.log(probability, 2)
        return entropy
    
    from math import log
    from collections import Counter
    def compute_entropy_my_python(data):
        """Compute entropy on bytearray `data`."""
        length = float(len(data))
        counts = (count / length for count in Counter(bytes(data)).values())
        return sum(-pro * log(pro, 2) for pro in counts)
    
    from numpy import bincount, random, uint8
    from scipy.stats import entropy
    def compute_entropy_scipy_numpy(data):
        """Вычисляем энтропию bytearray `data` с SciPy и NumPy."""
        counts = bincount(bytearray(data))
        return entropy(counts, base=2)
    
    from time import process_time
    NUM = 1000000
    VAL = random.randint(0, 256, size=(NUM, ), dtype=uint8)
    
    if __name__ == '__main__':
        start = process_time() 
        print(compute_entropy_pure_python(VAL))
        print(process_time()  - start)
    
        start = process_time() 
        print(compute_entropy_my_python(VAL))
        print(process_time()  - start)
    
        start = process_time() 
        print(compute_entropy_scipy_numpy(VAL))
        print(process_time()  - start)
    

    Итог:
    (projects) C:\projects>python pure_python.py                                                                                                                      7.999802815300323 - стат энтропия                                                                                                                                                                
    0.390625   - это скорость кода из статьи                                                                                                                                                                            
    7.999802815300329 - стат энтропия                                                                                                                                                                   
    0.09375  - это скорость нормального python кода                                                                                                                                                                             
    7.999802815300324 - стат энтропия                                                                                                                                                                 
    0.015625  - это скорость c nympy
    

    отличия ну точно не в сотни раз.
    Увы, повторить эксперимент с рустовской библиотекой я так и не смог. Но, что то мне подсказывает, что цифры будут не столь оптимистичны.
  • Виртуальные дегустации в Microsoft Teams: новый мир для старых вин
    0
    Привет, я из Австрии из winePad. Онлайн-дегустации это устоявшийся за 4 месяца у нас тут метод проведения дегустации, отходящий на второй план из-за снятия карантина. В основном тут все используют zoom, так что вброс про Microsoft Team не засчитан.
    Пробники рассылаются по почте за 2 дня до дегустации. Благо почта тут работает отлично.
    Затраты на подготовку к дегустации не окупается ни разу.
    Я на камере, организация первой дегустации
    Мы провели 5 дегустаций, записи вроде были на youtube. Основной приход — это после дегустационные продажи понравившихся вин. Но вот только вино теряет во вкусе при такой организации. Потому покупок было немного. Хотя народу было по 50 человек.
    Было 4 модератора групп по 10-12 человек и один сомелье ведущий.
    Очень понравилась дегустация, когда были приглашены производители вин и они получали по 10-15 минут времени на рассказ про свое вино. Это просто заслушаться можно! Эта дегустация началась в 20:00 и закончилась в 4:30 утра. Народ сидел, спрашивал, общался. Меня это удивило. Я сам свалил часа в два ночи.
    Весело… и неэффективно. Потому эта статья максимум реклама неудобной МТим и не более. А, да, дегустировал тут три недели назад их Rosso di Montalcino 2018 гавно ну очень на любителя.
  • Группировка вебсокет соединений для асинхронного фреймворка Starlette
    0

    Андрей, привет. Спасибо за пример из старлет, гляжу на него регулярно раз в полгода и пока не решился. Пока на любых примерах применения старлет или же торнадо я вижу, что придется все ещё работать с Джанго.
    Теперь вопрос по коду:
    У тебя _remove, _validate_name, _clean_expired объявлены нативными корутиновыми функциями, хотя они не возвращают незапущенную корутину. По идее это противоречит pep0492. Вероятно я здорово отстал от современного питона. Подскажи в чем смысл такого определения по твоему?
    Вопрос второй, а не правильнее ли было создать менеджер каналов со своими методами, а то как то странно видеть работу с голым глобальным словарем?

  • Django ORM для начинающих | Оптимизируем запросы
    0
    Либо я не понимаю гениальности этих решений, либо автор и комментатор чего-то не понимают в джанго:
    Authors.objects.filter(posts__id__isnull=False).distinct() — все авторы
    Authors.objects.filter(posts__title__icontains=«кодзима гений»).delete() — выборка авторов по определенному тексту в заголовке поста.
  • Django ORM для начинающих | Оптимизируем запросы
    +2
    Вот же знатные Django-воды на начинающего накинулись. Видно же что зеленый ещё.

    Теперь по делу:

    Автор, не поверишь, у тебя str(blog_obj) или str(author_obj) в некоторых случаях будут работать неправльно. Прелагаю тебе найти ошибку самостоятельно.

    Post.objects.first().blog.id можно сделать не только как Post.objects.first().blog_id а еще и Post.objects.values_list('blog__id', flat=True)[0] как и Post.objects.values_list('blog_id', flat=True)[0] как и Post.objects.first().only('blog__id').blog_id и еще много вариантов, появление каждого в проекте имеет свою причину. Попробуй померить время с only.

    Кроме этого не факт, что поле связи с блогом будет иметь форму «rel_obj»_id, я бы сказал, что это наиболее часто встречающийся случай и только.

    Использование django-extensions для queryset explain не нужно, и продолжает использоваться только по причине отвратительной документации Django в целом и отсутствия документации по объекту query в частности. query является обязательным аттрибутом queryset. В моей статье про djangoconf 2019 есть ссылка на видео про ORM, там докладчик про explain рассказывает.

    Кстати, статья про left join на хабре, что автор этой статьи прокомментировал, появилась только потому, что автор «left join» так и не понял, что сделать любой join возможно, правильно использовав queryset.query.

    Использование «all()» оправдано только в применении к object_manager, т.е. .objects.all() или когда не известно, что придёт в метод — менеджер или queryset.
    Если любой метод возвращающий queryset применен, то all() излишен.

    В остальном согласен с комментаторами, в документации информации побольше.
  • Django: краткое руководство по интернационализации
    0
    а можете подробнее рассказать, как это потом на фронтэнде решается?
  • Django: краткое руководство по интернационализации
    +3
    Слежу за темой интернационализации сайтов с 2009 года. Бегло говорю на трех языках(de, en, ru), в планах изучить итальянский и испанский(что бы смачно ругаться).

    В 2010 я с, уже бывшей, супругой — мы создали бюро мультиязычной поддержки в Австрии. Сначала это было создание мультиязычных PHP проектов, в основном мутации замшелой typo3, последние 5 лет я работаю с Django.

    В моем проекте winePad 7 языков: de/en/it/fr/nl/es/ru, планируем добавить венгерский и бельгийский. Объем переводов — 14 000 языковых констант плюс около 2 000 000 описаний, которые добавляются по 500 в день, и их надо переводить. Проект живет с 2011 года, за это время было много идей, как это все должно работать.

    В статье рассказано, как сделать перевод констант, причем предложен не самый лучший вариант. Объясню:
    Сидят у меня семь специализированных переводчиков, им нужен набор текстов, которые они могут перевести, откорректировать, внести, проверить, как выглядит на демо сервере, откорректировать еще раз, если криво выглядит в контексте — еще раз откорректировать, и, если все ок, выкатить на сервер.

    Работа с PO/MO файлами папки locales это ад для любого «не программиста», а если что задеть, так вообще все падает. Напомню, что еще и сервер надо перезапускать после каждого обновления переводного файла, каждого языка.

    Подходящим решением показалась django-rosetta, после ее установки стало немного проще. Но ненадолго. Розетта позволяет из бэкэнда переводить текстовые константы, причем она визуально разбивает таблицы переводов по языкам. Переводчикам понятно, есть выгрузка в эксель, можно переводить в специализированном переводческом по, и обратно загружать переводы. Вроде бы чего еще надо? Но тут выяснились и неудобства.
    • Розетта теряет переводы. Через неделю работы выяснилось, что некоторые переводы стали пропадать. Конечно косяк был найден (не устранен, кому надо — копайте в розетте способ обработки po файлов), мои переводчики оповещены.
    • Компиляция в MO и рестарт сервера. Это доверять переводчикам нельзя, настройка авто-рестарта после каждого обновления на продакшн не подходит, остается только вручную. Пока остановились на регулярном ночном авто рестарте сервера.
    • Безопасность. Невозможно настроить права доступа к переводам для разных переводчиков. Если редактор поправил языковую константу, то ее опять может поправить рядовой переводчик. История правок не сохраняется, невозможно проконтролировать кто и когда этот перевод сделал или поправил существующий.
    • Жесткость в языковой настройке. Есть только N языков в settings. Вот и переводите эти N языков. Про запас переводить еще два в Rosetta не получится.
    • Отсутствуют: Сопоставление переводов, настройка интерфейса, процентная плотность выполненых переводов и т.д.

    Напомню, также, что упомянутая в статье рекомендация от самих создателей gettext, обрамлять переводные константы в коде маркером "_()", это тот еще выстрел в ногу для соблюдающих стандартную конвенцию использования Single Underscore. (2.3.2. Reserved classes of identifiers)

    Кроме этого, за долгое время работы стало понятно, что писать константы осмысленными конструкциями _('Grape variety') хуже, чем маркировать их типа _('APP_15_71'). Инородный маркер при тестировании четко дает знать, что этот перевод пока отсутствует. Ну и при Дедлайне помогает переводчикам сначала перевести самый замечаемый контент.

    Но Языковые константы, те, что вы пометили тегом trans в шаблонах или обернули в gettext, — это только мелкая часть тех сложностей, с которыми вы столкнетесь, когда захотите говорить о настоящей мульти-язычности. Реально, все константы когда-нибудь будут переведены на 80% и вы, скорее всего, на этом успокоитесь.

    И когда основной темой для вас станет перевод данных из базы, вот тут-то и начнется рубилово…
    Я отлично понимаю, что этот вопрос останется актуальным максимум лет на 10-15, пока формируются надежные языковые базы автопереводчиков типа Google Translator. Пока же доверять им важные тексты никак нельзя:

    Один из наших бывших переводчиков немного поленился и внес нам в базу около 1000 автопереводов Гугла. Жаль, что линчевание у нас запрещено, и все, что нам оставалось — это переводчика уволить. Но тут и там иногда еще проскакивает гугло-перевод: «По мнению Джима-Отсоса....» В исходнике это был James Suckling, Internationally acclaimed wine critic and journalist.

    Так вот про рубилово. Если вы начнете думать, как переводить базу, то перед вами встанут решения:
    • хранить жестко заданное количество переводов прямо в таблицах моделей (django model translations, django-model-translate и т.д.). Новый язык — миграция базы, новое переводное поле — миграция. миграция, миграция....
    • Хранить переводы в PO файлах (упаси вас бог от этого). Рестарт сервера вам в помощь. И еще один и потом еще… Ой, а у меня переводы потерялись… А можно сервер сейчас стартовать...
    • Хранить переводы в структуре EAV (HVAD, Parler). N+1 запрос, и еще один и еще...


    Для winePad в конечном итоге я написал свой переводчик данных из базы — django-tof (лежит на githab). В TOF я скрестил Ежа с Ужом: простоту из model-translation с гибкостью EAV, но ад теперь начался у генератора текстов SQL запросов.
    Кому интересно, можете использовать as-is или поучаствовать в доработке.

    Кроме этого, во всех моих проектах переопределен шаблонный тег {% trans %}. Я использую вместо переводных констант данные из базы, для переводчиков — работает надежнее розетты, для дизайнеров шаблонов ничего не поменялось, просто другой load, для пользователей — быстродействие, как и у родного тега, c тем преимуществом, что не требуется каждый раз делать makemessages/compilemessages и рестарт сервера.

    В итоге, могу сказать, что тема пелотки мультиязычности еще очень, как не раскрыта, и перевод только констант, как рассказано в статье, это маленькая песчинка на верхушке интернационального айсберга. В котором еще есть перевод чисел и других значений, и дат и много чего еще, о чем ни автор, ни я, даже не вспомнили.
  • Нас Django вкус волнует и манит
    0
    что меня удивит — лежит в зоне правки нескольких объектов:
    Возможность инлайнов в середине фиелдсета формы админпанели.
    (Правится переопределением change_form)
    Возможность переменных фиелдсетов в формсетах (Правится переопределением __iter__ филдсета)
    Асинхронные формсеты (в текущей реализации невозможно)
    Очень удивит, если появится документация по объекту query
    Отказ от жесткой привязки к jquery тоже порадует.
    То что менеджер шаблонов сделали асинхронным… как то все равно. Или там еще что-то изменилось?
  • Нас Django вкус волнует и манит
    0
    — я все правильно понял?
    — не всё.

    В коде метода get ошибка логики. Еще нет программы которая использует этот метод, еще нет примера кода, а ошибка уже есть: алгоритм get создает объекты в случае, когда создавать их не должен вообще. по-моему мнению — эта ошибка. Исправить ее в джанго возможности нет. Потому есть рекомендация минимизировать последствия в тех случаях, когда действительно используется get.
  • Нас Django вкус волнует и манит
    0
    Спасибо.
  • Нас Django вкус волнует и манит
    0
    «Если get возвращает миллион записей...» — get возвращает один объект или ошибки. В процессе работы GET может создать много объектов на основе записей, возвращенных из базы.

    Эта логическая ошибка в стандартном методе get заключается в том, что на 9 строке метода создаются объекты, которые, если их можно было создать больше одного — создаваться не должны были в принципе. А они создаются, и только потом проверяется их количество.

    Кстати, когда выпал MultipleObjectsReturned, на обработке ошибки воспользоваться этими УЖЕ созданными «MultipleObjects» нельзя.
  • Нас Django вкус волнует и манит
    0
    Противоречие в том, что моя фраза «В итоге вы могли получить несколько миллионов объектов в памяти, только для того, чтобы узнать, что найден более, чем 1 объект.» не говорит, что результатом работы метода GET будет возврат двух и более объектов.

    однако именно она была приведена с комментарием «вот же», как пример того, что результатом работы метода GET будет возврат более одного объекта.
  • Нас Django вкус волнует и манит
    0
    Речь идет о методе GET в родном коде django (django/db/models/query.py). Я описал как он работает:
    Объекты сохраняются в "_result_cache".
    Если обьект один — Get вернет ссылку на первый и единственный объект в "_result_cache"
    GET выдаст ошибку «DoesNotExist» если _result_cache пустой
    GET вернет MultipleObjectsReturned, при этом "_result_cache" будет заполнен несколькими объектами и их количество не учитывается.
    _result_cache хранится в памяти, методом GET не возвращается.
  • Нас Django вкус волнует и манит
    0
    метод get возвращал и возвращает только один объект или выдает ошибки. Ни в коде, ни в моем тексте я не вижу упоминаний что get по окончанию возвращает что-то другое.

    прошу указать: где в коде или тексте статьи ошибка, подразумевающая, что результатом работы метода GET будет возврат двух и более объектов.
  • Нас Django вкус волнует и манит
    0
    Пробовал. Десять открытых тикетов на сайте Джанго проекта и один несостоявшийся пулл реквест про конвертацию флоат/децимал- писал в предыдущей статье. В итоге плюнул, правим в нашем проекте под себя.
  • Нас Django вкус волнует и манит
    +1
    По логике, данная функция должна инициировать и возвращать только один объект, и делать это только в том случае, если объект один.

    В реальной Django это невозможно сделать за один запрос. Потому текущая логика метода такова:
    • Проинициализировать объекты данными из запроса, будет проинициализировано столько объектов, сколько возвращено строк,
    • Объекты сохраняются в "_result_cache".
    • Если обьект один — Get вернет ссылку на первый и единственный объект в "_result_cache"
    • GET выдаст ошибку «DoesNotExist» если _result_cache пустой
    • GET вернет MultipleObjectsReturned, при этом "_result_cache" будет заполнен несколькими объектами и их количество не учитывается.


    В Django 3 появилось ограничение в 25 строк, это значит, что в sql запроса есть «LIMIT». Во всех предыдущих версиях этого ограничения не было вообще, и мы поставили у себя в проекте ограничение на количество возвращенных строк до 2х.
    В этом случае будут проинициированы максимум два обьекта. После чего Get выдаст ошибки, если получен иной результат, чем один объект.

    Ограничение на 2 объекта вместо 25 я предлагаю и для новой Django.
  • Нас Django вкус волнует и манит
    0
    Пробовал. Десять открытых тикетов на сайте Джанго проекта и один несостоявшийся пулл реквест про конвертацию флоат/децимал- писал в предыдущей статье. В итоге плюнул, правим в нашем проекте под себя.
  • Нас Django вкус волнует и манит
    0
    Если судить по тому, что ограничение на количество получаемых объектов методом get уже попало в официальный релиз Django 3, то получается, что я не один такой сказочный долбо§б.

    Я уже в статье отметил, что считаю, что в этой функции ошибка. Ошибка в логике: функция должна получать только один объект, если он есть. Не два, не 25, и не два миллиона. Жаль только, что мой манкипатчинг (смешное слово) не исправляет эту ошибку а только уменьшает количество получаемых объектов.
  • GeekUniversity открывает набор на факультет тестирования ПО
    0

    Разбит на несколько четвертей это как?

  • Электронная карта виноделия России. Замысел и наполнение
    0
    не там нажал ответ. фраза stilet69 была «Например понравился Новый берег марки Сира»
  • Электронная карта виноделия России. Замысел и наполнение
    0

    Предположу, что это привозной Шираз разлитый по бутылкам.

  • Управление зависимостями в Python: сравнение подходов
    0
    Как знать что принимает и возращает эта функция?

    В приведенном мною моем решении — никак. Полагаю, что для этой функции будет достаточно методов самодокументации с говорящими именами и можно добавить docstring. Вариантов много, ADR, предлагайте свои.

    return response.json()['url']

    Конечно же как и url так и ответы от разных сервисов, скорее всего, отличаются. И перенастройка только URL может привести к ошибке KeyError.

    Как логично заметил js605451 и позже еще и я отметил, в исходной функции много что прибито гвоздями, в том числе и ключ значения в ответе. Думаю, благодаря комментариям, автор статьи увидел это более четко.
  • Управление зависимостями в Python: сравнение подходов
    0

    Предположу, что понравится доклад и наработки про разделение бизнес логики на апрельском Джанго конф 2019. В моей статье на Хабре, ссылка есть, в третий день конференции.

  • Управление зависимостями в Python: сравнение подходов
    0

    Я не принимаю решение. Это код из статьи. API Key передается при инициализации класса и Я даже не знаю что это такое и откуда. А вот то, что ссылка захардкожена в коде функции, скорее всего недоработка. Как собственно и метод Post и заголовки и класс респонса. И ключ по которому получаем результат.