Ответы пользователя по тегу Django
  • Почему при запуске Django тестов через ./manage.py не работают патчи?

    Assargin
    @Assargin
    Перед ответом смотрю наличие ✔ в ваших вопросах
    Скорее всего, вы патчите что-то, что в случае вызова через manage.py импортится до того, как запатчится.
    Скорее всего, вы пытаетесь пропатчить исходную сущность в сторонней либе (или даже стандартной), а надо патчить то, что импортируете к себе в модуль, сущность из которого тестируете.

    Например, у вас есть ф-я mypackage.mymodule.foo, где используется urlopen из urllib:
    from urllib.request import urlopen
    
    def foo():
      ...

    И для этой ф-и вы хотите написать тесты, запатчив вызов urlopen.
    Потенциально нерабочий вариант:
    @patch("urllib.request.urlopen")
    def test(urlopen):
      ...

    Точно рабочий вариант:
    @patch("mypackage.mymodule.urlopen")
    def test(urlopen):
      ...


    UPD: а вообще, видеть бы код теста и самой тестируемой ф-и
    Ответ написан
  • Как организовать микро слипы в задаче celery?

    Assargin
    @Assargin
    Перед ответом смотрю наличие ✔ в ваших вопросах
    Явное указание ETA ради лимитирования - так себе механизм. Если воркер вдруг умрёт, то после перезапуска новому воркеру придут на выполнение сразу все "опоздавшие" задания, и чем дольше воркер лежал, тем больше будет пачка. Также, сложно регулировать проставление абсолютного значения ETA, если вдруг придётся делать это одновременно для нескольких потоков рассылок, чтобы они, выполняясь параллельно, не выбирали весь лимит.

    Ещё в Celery есть механизм rate limit на тип таска, правда, он работает только в пределах 1 воркера.

    Т.е. в тех нечастых случаях, когда на 1 очередь запускается более 1 воркера + для случаев, когда лимит с типом таска матчится не 1:1 (например, лимит на API общий, а методов в этом API может быть 100500, каждый дёргается с помощью отдельного типа таска) - есть реализация на основе token bucket.
    Ответ написан
    Комментировать
  • Почему не сохраняется m2m?

    Assargin
    @Assargin
    Перед ответом смотрю наличие ✔ в ваших вопросах
    Итак, вы сохраняете из админки, а это значит, что ваш сигнал (post_save надо, pre_save тут точно мимо) отрабатывает сразу после того, как будет сохранён объект User. Пока всё ок.

    Но именно с админкой есть нюанс: после того, как сохранится основная модель и выполнятся соответствующие этому действию сигналы, начнётся сохранение m2m связей, которые 100% у вас есть на странице админки, и перезапишут те данные, которые вы миллисекундами ранее сохранили с помощью сигнала.

    У меня была когда-то похожая проблема, и если мне не изменяет память, я создавал свой сигнал, который вызывал из переопределённого метода класса админки модели после сохранения вообще всего, а в обработчике своего кастомного сигнала уже спокойно работал с m2m-связями без этих проблем.

    Также, можно поиграться с имеющимся в Django сигналом m2m_changed, но это будет костыль, потому что этот сигнал будет вызван 2N раз, где N - число добавлений/удалений из m2m.
    Ответ написан
  • Как выполнять комманду exec (docker-compose), чтобы файлы созданные впоследствие нее пренадлежали текущему пользователю на хост машине?

    Assargin
    @Assargin
    Перед ответом смотрю наличие ✔ в ваших вопросах
    Коль вы не даёте конкретно запускаемую вами команду и содержимое конкретно ваших docker/compose-файлов, то вот вам соответствующий вопросу ответ: у вас где-то ошибка, потому что работать должно.
    user@user-workstation:/tmp/test$ docker container run --rm -v ${PWD}:/tmp -u $(id -u ${USER}):$(id -g ${USER}) ubuntu:18.04 touch /tmp/it.is.my.file
    user@user-workstation:/tmp/test$ ll
    итого 20
    drwxrwxr-x  2 user user   4096 янв 22 13:55 ./
    drwxrwxrwt 23 root root  16384 янв 22 13:55 ../
    -rw-r--r--  1 user user      0 янв 22 13:55 it.is.my.file
    user@user-workstation:/tmp/test$ rm it.is.my.file 
    user@user-workstation:/tmp/test$ docker container run --rm -v ${PWD}:/tmp ubuntu:18.04 touch /tmp/it.is.my.file
    user@user-workstation:/tmp/test$ ll
    итого 20
    drwxrwxr-x  2 user  user   4096 янв 22 14:01 ./
    drwxrwxrwt 23 root  root  16384 янв 22 14:01 ../
    -rw-r--r--  1 root  root      0 янв 22 14:01 it.is.my.file
    user@user-workstation:/tmp/test$
    Ответ написан
    1 комментарий
  • Как в Django сделать механизм, при котором через объединённые формы можно изменять значений у нескольких записей сразу?

    Assargin
    @Assargin
    Перед ответом смотрю наличие ✔ в ваших вопросах
    Если подходит вариант реализовать это в обычной админке Django, то решением может быть ModelAdmin.list_editable. Этот атрибут в джанге есть давно. И когда-то я его даже использовал.

    Есть 1 подводный камень, по крайней мере года 3 назад он точно был: если в админке одной и той же модели изменяли данные более 1 человека, то данные могли непредсказуемо потеряться и/или измениться.

    Поковыряв тогда исходники, я выяснил, что это происходит из-за того, что при сохранении отредактированных данных джанга опирается на относительное положение объекта (!) в кверисете (!!) в текущий момент!!!
    Т.е., популярно выражаясь: не "сохрани значение Super Item в поле title инстанса id=345 модели MyModel", а "сохрани значение Super Item в поле title инстанса, который в текущем кверисете MyModel.objects.filter(category="Items") на странице №2 находится на 14-й позиции".

    Причём сначала может показаться логичным, мол, классический кейс - одни и те же данные изменяют 2 и более человека, конечно можно получить перезаписывание, но если бы! Даже просто добавив новый объект этой модели, причём даже не из админки, можно запросто нарушить вот эту вот относительную "адресацию".
    Ответ написан
  • Как использовать собственные стили каждого приложения в шаблоне Django?

    Assargin
    @Assargin
    Перед ответом смотрю наличие ✔ в ваших вопросах
    и есть html файл который определяет по ссылке какое приложение сейчас используется.

    Не надо так.
    В Django есть возможность в каждом приложении создавать свои шаблоны и static файлы - css, js и т.п. Шаблоны могут наследоваться друг от друга - это ключевой момент для логичной их организации даже для небольшого проекта, не говоря уже про большие.
    Можете создать один общий родительский шаблон-лэйаут на весь проект, в нём подключить общую для проекта статику (всякие там jquery и прочие либы).
    В каждом приложении в свою очередь создаётся свой лэйаут или шаблон, отнаследованный от общего, и в нём уже дополнительно подключаются конкретные css/js конкретного приложения.
    Погуглите про наследование шаблонов, про блоки в них и про то, как переопределять эти блоки в отнаследованных шаблонах.
    Ответ написан
    Комментировать
  • Как настроить uwsgi для работы с Django и pipenv?

    Assargin
    @Assargin
    Перед ответом смотрю наличие ✔ в ваших вопросах
    [uwsgi]
    project = cv-base
    ...
    chdir = %(base)/%(project)/ems
    ...
    module = %(project).wsgi:application

    Итого у вас получается, что module превращается в cv-base.wsgi:application, но в вашем дереве проекта внутри chdir нет cv-base. Вероятно, значение module должно быть ems.wsgi:application
    Ответ написан
    2 комментария
  • Как вывести данные из django в шаблон word?

    Assargin
    @Assargin
    Перед ответом смотрю наличие ✔ в ваших вопросах
    Так гугл же!
    Первое, что гуглится по запросу python docx template - библиотека docxtpl
    Под капотом используется известная в этих кругах либа python-docx для возни с документами + также популярная jinja2 для, собственно, шаблонизации.

    И да - про именно .doc, старый добрый бинарный проприетарный формат, скорее всего, придётся забыть. Только .docx.

    в нём есть некоторый шаблон, подставляются значения из самой базы

    Если нет возможности или желания переводить ваш синтаксис шаблонов в jinja2 - тогда берите напрямую python-docx и сами пишите логику по замене токенов в шаблонах на нужные значения из БД.
    Ответ написан
    3 комментария
  • Как правильно сохранить картинку из url в django models.ImageField?

    Assargin
    @Assargin
    Перед ответом смотрю наличие ✔ в ваших вопросах
    Сохранение картинки работает, а вот формирование пути сделано с ошибкой
    def save_model(self, request, obj, form, change):
        r = requests.get(url, stream=True)
        r.raw.decode_content = True
        obj.image.save(os.path.join('img', '{}.jpg'.format(slugify(unidecode(obj.title)))), r.raw)
        obj.save()

    os.path.join формирует путь из директорий и имени файла, но имя отдельно взятой папки или файла им формировать не нужно.
    Ответ написан
  • Как наиболее просто опубликовать проект Django на DigitalOcean?

    Assargin
    @Assargin
    Перед ответом смотрю наличие ✔ в ваших вопросах
    У digitalocean есть хорошие рабочие step-by-step мануалы, как развернуть то или иное. Не исключение и django:

    Как наиболее просто

    Самым простым способом может быть использование преднастроенного образа django. Правда, сам я так не делал.
    Ответ написан
    5 комментариев
  • Как к текущей дате прибавить строковую дату?

    Assargin
    @Assargin
    Перед ответом смотрю наличие ✔ в ваших вопросах
    Используйте для хранения freeze_time число секунд, так будет удобнее хранить в БД и оно удобно конвертируется в/из timedelta, который уже можно прибавлять к datetime.
    Пример:
    >>> from datetime import datetime, timedelta, now
    >>> begin_date = datetime(2017, 9, 1, 0, 0, 0)
    >>> end_date = datetime(2017, 9, 30, 0, 0, 0)
    >>> freeze_time = end_date - now()
    >>> freeze_time
    datetime.timedelta(2, 17264, 411894)
    >>> freeze_time.total_seconds()
    190064.411894
    >>> freeze_time = int(freeze_time.total_seconds())
    >>> freeze_time
    190064
    >>> now() + timedelta(seconds=freeze_time)
    datetime.datetime(2017, 9, 30, 0, 1, 1, 371159)
    Ответ написан
    1 комментарий
  • Как реализовать подгрузку контента по клику в Django?

    Assargin
    @Assargin
    Перед ответом смотрю наличие ✔ в ваших вопросах
    Из необходимого:
    1. View основной страницы отображения новостей
    2. JS-код, который делает ajax-запрос на сервер за следующими X новостями
    3. View, который по ajax отдаёт данные (или уже готовый html) следующих X новостей
    4. JS-код, который дополняет список новостей на странице полученными X новостями
    Ответ написан
    Комментировать
  • Как модифицировать шаблон в Django, не затрагивая верстки по умолчанию?

    Assargin
    @Assargin
    Перед ответом смотрю наличие ✔ в ваших вопросах
    1) Как это исчезает? В отнаследованном шаблоне всё остаётся как и есть в шаблоне-предке.
    Т.е., если создать шаблон в проекте, и написать в нём лишь
    {% extends 'admin/base_site.html' %}
    то это будет, по сути, тот же самый шаблон.
    Приведу пример из своего проекта, по нему вы сможете сориентироваться. Можно переопределять блоки, расширяя их (добавляя то, что нужно), или даже убирая контент из них.
    Пример шаблона
    {% extends 'admin/base_site.html' %}
    
    {% load js_storage %}
    {% load admin_static %}
    {% load i18n %}
    {% load pipeline %}
    
    
    {% block extrastyle %}
        {{ block.super }}
        {% stylesheet 'Jcrop' %}
        {% stylesheet 'admin-core' %}
    {% endblock %}
    
    {% block extrahead %}
        {{ block.super }}
        {% js_storage_out %}
    {% endblock %}
    
    {# Из заголовка удалили конкретную для страницы крошку, оставив только site_title #}
    {% block title %}{{ site_title|default:_('Django site admin') }}{% endblock %}
    
    {# Добавили логотип #}
    {% block branding %}
        <img src="{% static "images/logo_50.png" %}" class="logo" />
        {{ block.super }}
    {% endblock %}
    
    {# Убрали приветствие пользователя #}
    {% block welcome-msg %}
    {% endblock %}
    
    {# Убрали ссылку View Site #}
    {% block userlinks %}
        {% if user.is_active and user.is_staff %}
            {% url 'django-admindocs-docroot' as docsroot %}
            {% if docsroot %}
                <a href="{{ docsroot }}">{% trans 'Documentation' %}</a> /
            {% endif %}
        {% endif %}
        {% if user.has_usable_password %}
        <a href="{% url 'admin:password_change' %}">{% trans 'Change password' %}</a> /
        {% endif %}
        <a href="{% url 'admin:logout' %}">{% trans 'Log out' %}</a>
    {% endblock %}
    
    {% block footer %}
        {{ block.super }}
        {% javascript 'jquery-mousewheel' %}
        {% javascript 'js-cookie' %}
        {% javascript 'Jcrop' %}
        {% javascript 'plupload' %}
        {% javascript 'admin-core' %}
    {% endblock %}

    2) Кастомизировать шаблоны админки для конкретной модели можно, переопределяя их в папке шаблонов проекта. Например, если у меня есть приложение users, в нём есть модель user, и для неё мне нужно кастомизировать шаблон списка объектов, то я создаю файл templates/admin/users/user/change_list.html и делаю там, что мне нужно
    Пример переопределения шаблона админки для модели
    {% extends 'admin/change_list.html' %}
    
    {% block extrahead %}
        {{ block.super }}
        <script type="text/javascript">
            var url = js_storage.url_users_user_show_user_password;
            (function($) {
                $(document).ready(function($) {
                    $('#result_list td.field-rawpassword').click(function(event){
                        var $target = $(event.currentTarget);
                        var user_id = $target.closest('tr').find('td.action-checkbox input[type=checkbox]').val()
                        if(!$target.data('shown')){
                            $.get(url, {user_id: user_id}, function(data, status, xhr){
                                $target.html('<span style="font-family: Monospace">' + data.raw_password + '</span>');
                                $target.data('shown', true);
                            });
                        }
                    });
                });
            })(django.jQuery);
        </script>
    {% endblock %}

    Ответ написан
    6 комментариев
  • Django ImageField отображение изображения, в чем дело?

    Assargin
    @Assargin
    Перед ответом смотрю наличие ✔ в ваших вопросах
    У вас опечатка в строке, где вы добавляете урлы медиафайлов, вот исправленное, сравните:
    ..
    if settings.DEBUG:
        urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
        urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
    ..
    Ответ написан
    1 комментарий
  • Как отобразить архив статей?

    Assargin
    @Assargin
    Перед ответом смотрю наличие ✔ в ваших вопросах
    К сожалению, на одну и ту же модель нельзя зарегистрировать более 1 класса админки.
    Есть вариант с прокси-моделью, посмотрите здесь. Там даже тема схожая - публикации.
    Ответ написан
    Комментировать
  • Что еще добавить в юнит тест для функции сортировки?

    Assargin
    @Assargin
    Перед ответом смотрю наличие ✔ в ваших вопросах
    • в setUp создайте несколько объектов Slide
    • добавьте в вызов
      self.client.post(reverse("article:article_sorting"), follow=True)
      json, который сменит сортировку этьм объектам
    • добавьте ещё одну проверку, помимо статуса (и, возможно, json ответа), что объекты Slide сменили свою сортировку
    Ответ написан
    8 комментариев
  • Как задать permission для собственного метода?

    Assargin
    @Assargin
    Перед ответом смотрю наличие ✔ в ваших вопросах
    В вашем особом случае можно применить декорирование прям в urls.py, как показано вот здесь, только декоратором будет permission_required

    Но вообще, такой подход - запихать всё в одну вьюху и какую-то логику вынести в urls.py - забраковал бы :)
    Ответ написан
  • Django. Как зарегистрировать посетителя (гостя), после отправки формы заказа?

    Assargin
    @Assargin
    Перед ответом смотрю наличие ✔ в ваших вопросах
    Если оставить за бортом спорные моменты в таком процессе, то:

    Автоматическое создание пользователя
    У стандартного UserManager'а есть метод create_user. Если у вас переопределённая модель пользователя, проследите, чтобы UserManager для вашей модели был актуальный. Если вы меняли поля, которые фигурируют в этом методе, возможно, вам потребуется создать свой UserManager на основе стокового.

    Аутентификация пользователя
    Залогинить пользователя, на удивление, совсем легко, есть функция login

    Ну а редирект (на ЛК) после создания пользователя и его успешного логина вы, наверное, знаете как сделать.
    Ответ написан
  • Как запускать Celery сразу с учетом виртуального окружения?

    Assargin
    @Assargin
    Перед ответом смотрю наличие ✔ в ваших вопросах
    Ну так, у вас в проекте, наверное, есть файл с зависимостями. requirements.txt, например. Где помимо прочих зависимостей, также должен быть прописан сельдерей нужной версии:
    ..
    celery==X.Y.Z 
    ..

    На проде одним из шагов вашего процесса релиза, наверное, является установка/обновление этих зависимостей:
    pip install -r /path/to/requirements.txt
    Следовательно, вы имеете в вашем venv'е установленный celery. Наверное.
    Ну и просто запускайте его оттуда, и всего делов. Тем же способом можно, просто путь до исполняемого файла будет указывать внутрь вашего виртуального окружения с проектом, типа:
    /path/to/virtualenv/bin/celery --params ....
    Ответ написан
    1 комментарий
  • Как в django admin сортировать в редакторе поля в выпадающем списке?

    Assargin
    @Assargin
    Перед ответом смотрю наличие ✔ в ваших вопросах
    Посмотрите 2 топовых ответа, в них описаны 2 возможных способа решения вашей задачи.
    https://stackoverflow.com/questions/18742632/how-t...
    1. Задать Meta.ordering в модели, на которую ссылается ваш внешний ключ
    2. Переопределить метод formfield_for_foreignkey в классе админки вашей модели
    Ответ написан
    Комментировать