Ответы пользователя по тегу Django
  • Как изменить БД для тестов?

    @hsc
    full stack python back-end developer
    Привет. Создайте отдельный settings.py для тестов и запускайте на нем. Еще совет: используйте in-memory sqlite - быстрее в разы.
    Ответ написан
    3 комментария
  • Как в Django передать данные из модели в шаблон в обход views?

    @hsc
    full stack python back-end developer
    Для начала: https://www.python.org/dev/peps/pep-0020/
    Один из пунктов там "явное лучше неявного".

    Views в django на то и придуманы чтобы передавать данные и делать это явно, но то, как это сделать всецело зависит от Вас. Вы правы, нет смысла во всех вьюхах городить огород с передачей одних и тех же данных, тем более, если они общие для большинства шаблонов, но ни custom context processor, ни тем более custom template tag Вас не выручат так, как может одна простая конструкция:

    где-нибудь в utils.py
    def base_context(request):
        return Context({
            'user': request.user,
            '...': '...',
        })


    Где-нибудь в views.py:
    def view(request):
        context = base_context(request)
        context['this view specific data'] = 'happy coding'
        return render_to_response('template.html', context)


    Таким образом Вы:
    1. Не захламляете общий request flow и сохраняете контроль над контекстом любой вьюхи. Context processors будут вызваны для любого рендера, тогда как такой подход позволит Вам всегда иметь минимум необходимых данных под рукой и полный контроль над всеми вьюхами.

    2. Передаете в контекст шаблонизатора только, что действительно должно в него попасть. Больше того, в отдельных вьюхах Вы даже можете переопределить базовые параметры, что не так удобно делать с context processors. (но лучше см. п.3)

    3. Можете расширить абстракцию как угодно, и создать хоть 2, хоть 3, хоть больше базовых контекстов под всевозожные ситуации (зависит от архитектуры).
    Ответ написан
    Комментировать
  • Как можно передать ссылку на экземпляр класса в другие модули, чтобы взаимодействовать с ним?

    @hsc
    full stack python back-end developer
    Не думайте о потоках как об объектах, потому что они ими не являются. Поток — это нить выполнения, которая во время инициализации принимает функцию, которую будет выполнять. После инициализации — это отдельный мини-процесс. Вызвать метод потока невозможно: у него их попросту нет. Можно вызвать метод дескриптора (объекта, который управляет потоком) но не самого потока. Отличием потоков от процессов является то, что потоки разделяют адресное пространство с процессом, который их породил. Это значит, что каждый поток имеет доступ к данным процесса и других потоков.

    Теперь о вариантах решения. Я их вижу несколько:
    1. Перед запуском потока создать proxy-объект, экземпляр класса, который будет описывать подходящую для вас структуру данных. В зависимости от задачи, может быть полезным посмотреть на Queue, он из коробки потоко-безопасен. После этого просто передать ссылку на этот объект в конструктор потока и общаться через него. Поток пишет в этот объект - django читает из него, и наоборот. Модель очереди для таких задач подходит как нельзя лучше, потому как нельзя гарантировать то, что поток подхватит задачу сразу по ее появлению, и другая задача не затрет предыдущую. Создавать proxy-объект нужно в такой точке, из которой выполнение процесса родителя не выйдет до остановки потока, иначе Вы рискуете потерять контроль над потоком или ловить "странные" ошибки.

    2: Если есть необходимость ставить перед потоком разные задачи может быть разумно вынести их хранение во внешние службы, например redis. Он очень быстрый и существенного оверхед даже на малинке не создаст. Общаться с ним можно через этот пакет. Если хотите сэкономить на tcp-трафике - запускайте redis на unix-сокете.
    Этот вариант потенциально избавит Вас от головной боли с синхронизацией задач.

    3: Если есть возможность и памяти хватает больше чем на 1 поток - RQ. Это — легкий менеджер очереди задач для python. По сути, то, что Вы и пытаетесь реализовать.
    Ответ написан
    7 комментариев