• Python selenium как нажать на элемент списка по значению input?

    @Sovetnikov
    технический директор pulsprodaj.ru
    Что-то вроде этого
    ec = EC.text_to_be_present_in_element((By.CSS_SELECTOR, 'input'), text='Бизнес')
    element = driver(ec)
    Ответ написан
  • Как заблокировать доступ на изменение только части полей?

    @Sovetnikov
    технический директор pulsprodaj.ru
    Можно поступить радикально. Контролировать изменения полей в сигнале pre_save для Model (надо сохранять в конструкторе или в create старые значения и потом сравнивать в pre_save)
    Как плюс будет то, что автоматически этот контроль будет работать и в django admin и в других местах.

    Ролевую модель сделайте используя группы и доступы Django. Правильнее конечно через доступы, а доступы уже пользователям или группам назначайте.
    Ответ написан
    Комментировать
  • Как сделать селект, который определяет содержимое другого селекта'а?

    @Sovetnikov
    технический директор pulsprodaj.ru
    Если именно Django + Admin, то по сути вот тут разбирали Django 2.х Admin. Как сделать выборку одного поля, в зависимости от выбранного элемента в другом (ForeignKey)?
    Там несколько решений, но скорее всего JS.
    Ответ написан
    Комментировать
  • Что лучше/правильнее применять для создания View generic.ListView и подобные или функцию render?

    @Sovetnikov
    технический директор pulsprodaj.ru
    Применяйте то, что вы умеете.
    1. Class Based Views - кому-то они удобнее, какие-то вещи с ними удобнее
    2. Function Based Views - по сути стандарт, каких-то ограничений они не накладывают на возможности
    3. ListView и т.п. - по ним в интернет мало подсказок и готовых решений, их скорее всего вам надо будет изучить по официальной документации и покопавшись у них в исходниках

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

    @Sovetnikov
    технический директор pulsprodaj.ru
    Как разработчик .NET C# переключившийся на Python+Django могу однозначно рекомендовать :)
    Ответ написан
    2 комментария
  • Как загружать большие данные через api?

    @Sovetnikov
    технический директор pulsprodaj.ru
    1. Про нехватку памяти проверьте сначала, запутить скрипт и в консоле запустите top - наблюдайте как растёт память.
    2. Если у вас 5млн записей, то вы принципиально неправильно сделали работу. Вы зачитываете в память сразу всё, хотя ваша единичная операция требует всего одного продукта.
    Пишите код правильно, а не делайте костыли, которые восстанавливают работу после того как что-то у вас отвалилось.
    3. Вы поулчаете данные по 1000 позиций в connect ... встройте туда же вашу обработку для Product, тупо копипастом хотя бы - это решит проблемы с памятью, если проблема именно в этом.
    Обрбатывайте по 1000 позиций за раз.

    Ещё поясню:
    - когда заканчивается память - это нештатная ситуация для всей системы и для СУБД в первую очередь, есть вероятность потерять данные
    - сохранять состояние offset для client.service.doGetItemsList тоже хорошая идея для случаев обрыва связи, но это только если она у вас рвётся
    Ответ написан
    1 комментарий
  • Django 2.х Admin. Как сделать выборку одного поля, в зависимости от выбранного элемента в другом (ForeignKey)?

    @Sovetnikov
    технический директор pulsprodaj.ru
    Из коробки django-admin не поддерживает такие обновления на самой странице, только если в форме зададите свой queryset для поля которое соответствует FK из модели, но вы видимо хотите сделать именно на странице.

    Если у вас рядом на форме два FK поля, то пишите JS, который будет фильтровать второй в зависимости от значения первого. Только вам надо будет дополнительно на страницу в JS передать данные о связях второго FK с первым, чтобы фильтровать.

    А где у вас в модели страна с курортом связана?
    Вы же страну для Tours выбирать хотите?
    Ответ написан
    4 комментария
  • Подключиться к сокет соединению с ssl?

    @Sovetnikov
    технический директор pulsprodaj.ru
    1. Посмотрите браузером куда вас веб-сервер редиректит по 301 статусу.

    2. Вы соединяетесь с сокет сервером на 8060 порт ... а он поддерживает обращения по пути '/ws'? Не вижу его в routes.
    Вы же на domain:8060/ws соединение делаете, а не в nginx который обрабатывает "location /ws/" с пересылкой на 8060 порт.
    Ответ написан
    4 комментария
  • Как сделать так, чтобы исполнялись все декораторы в чат-боте Телеграм?

    @Sovetnikov
    технический директор pulsprodaj.ru
    1. У вас два раза определен handle_start ... возможно это и не помешает работе, но всё зависит от реализации декоратора подписки на событие message_handler.
    Переименуйте.

    2. А почему после команды "/start" от пользователя должно что-то ещё сработать?
    Видимо message_handler срабатывает только на первом хендлере у которого фильтр выполнился.
    Вы хотите чтобы сразу на одно сообщение сработали handle_start и ex_x и total?
    Ответ написан
  • Каким образом можно вывести значение python функции в html файл?

    @Sovetnikov
    технический директор pulsprodaj.ru
    Django micro-framework, web.py:
    from django.conf import settings
    from django.conf.urls import patterns
    
    if not settings.configured:
        settings.configure(
            DEBUG=True,
            ROOT_URLCONF='web',
            TEMPLATE_DIRS=['.'],
        )
    
    urlpatterns = patterns('',
                           (r'^$', 'web.index'),
                           (r'^show_data/$', 'web.show_data'),
                           )
    
    from django.shortcuts import render
    
    
    def index(request):
        return render(request, 'index.html', {})
    
    
    def show_data(request):
        from pay import get_data
        return render(request, 'show_data.html', {'data': get_data()})
    
    
    if __name__ == '__main__':
        from django.core.management import execute_from_command_line
    
        execute_from_command_line()
    Ответ написан
  • Стоит ли прикручивать websokets или асинхронность?

    @Sovetnikov
    технический директор pulsprodaj.ru
    websokets это для двусторонней коммуникации, не надо туда файлы запихивать (ну только если очень хорошо понимаете зачем).
    Так же файлы не надо запихивать в реляционную СУБД :)

    Единственное ... "здесь обработка файла в очереди (RabbitMQ)" это вы сообщение в очередь кидаете или какой-то код обработки менно в perform_create работает?
    Ответ написан
    3 комментария
  • Как получить поле объектов из inlines Django?

    @Sovetnikov
    технический директор pulsprodaj.ru
    Если при изменении статуса заказа надо отправить оповещение пользователям, то save_model в ModelAdmin это не самое лучше место, вернее даже худшее из приходяших на ум.
    Статус заказа может быть изменен и в других местах ... (до уровня тригеров в БД опускаться не будем).

    Используйте post_save сигнал. Только неудобство, что надо будет вручную определять изменился ли статус, на тостере было про это.

    Если уж хотите в save_model, то учитывайте что Order изменится в БД только когда транзакция закомитится (а вы уверены что у вас транзакции нет?) Соответственно:
    from django.db import connection
    connection.on_commit(lambda: send_order_email(obj.pk))

    И в send_order_email зачитывайте заказ и БД ...
    Если хотите ускорить работу send_order_email в некоторых случаях и иметь возможность передать ему уже загруженный order с prefetch_related например, то сделайте просто:
    def send_order_email(order):
       if not isinstance(order, Order):
            order = Order.objects.get(pk=order)
    Ответ написан
    Комментировать
  • Как организовать запуск скриптов на сервере?

    @Sovetnikov
    технический директор pulsprodaj.ru
    Если бывает, что падают парсеры (а они обязательно падают) - то celery однозначно.
    Более сложные workflow - dask.distributed. Celery canvas очень ограничен.
    Ответ написан
    Комментировать
  • Как скачивать файлы с www.reverse.it?

    @Sovetnikov
    технический директор pulsprodaj.ru
    Напишите им кто вы такой и зачем вам образцы, они рассмотрят вашу заявку.
    Доступ они предоставляют только профессионалам в области IT-безопасности.
    Ответ написан
    Комментировать
  • Как получить ошибки всех запросов?

    @Sovetnikov
    технический директор pulsprodaj.ru
    Надо каждый Promise пропустить через catch и возвращать саму ошибку:
    function apiRequest(success) {
        return new Promise(function (resolve, reject) {
            if (success) {
                resolve(success);
            } else {
                reject('err');
            }
        })
        .catch(function(err){
            return err;
        });
    }
    var p1 = apiRequest('1');
    var p2 = apiRequest();
    var p3 = apiRequest('2');
    var p4 = apiRequest();
    
    Promise.all([p1, p2, p3, p4])
    .then(function(res){
        console.log('Promise.all', res);
    })
    .catch(function(err){
        console.error('err', err);
    });

    Результат:
    Promise.all (4) ["1", "err", "2", "err"]
    Ответ написан
    Комментировать
  • Mysql: почему тормозит\зависает SELECT запрос в Percona XtraDB Cluster?

    @Sovetnikov
    технический директор pulsprodaj.ru
    1. Попробуйте запрос не в кластер, а напрямую в один из серверов
    2. Посмотрите план выполнения запросов на локальной копии и на боевом, сравните
    3. Проверьте блокировки в БД, может транзакции висят

    Если данные совершенно одинаковые, то либо статистика собранная настолько кривая (но не думаю), либо дело в сервере (может там память кончается и в своп всё ходит, памяти конечно у вас много но всё же? диск не переполнен? диски вообще живые, без ошибок?)
    Ответ написан
    5 комментариев
  • Как обработать форму django rest framework?

    @Sovetnikov
    технический директор pulsprodaj.ru
    Довольно мутные интерфейсы в DRF ... с ходу не разберешься, "Django" он называется видимо только потому, что просто умеет с Django ORM работать, интерфейсы и подходы как-то не очень Django-frendly

    Пишу весь код в одну кучу, критика приветствуется.
    from django.conf.urls import patterns
    from django.core.exceptions import PermissionDenied
    from django.db import models
    from django.db.models.base import ModelBase
    from django.utils.decorators import available_attrs
    from rest_framework.permissions import IsAuthenticated
    from rest_framework.status import HTTP_500_INTERNAL_SERVER_ERROR
    
    # Наш документ в models.py
    document_make_some_permission = 'document_custom_permission'
    
    
    class Document(models.Model):
        class Meta:
            permissions = [
                (document_make_some_permission, "make_some доступ"),
            ]
    
        @classproperty
        def make_some_permission(cls):
            """ Возвращает полный код доступа """
            return permission_code(cls, document_make_some_permission)
    
        name = models.CharField(max_length=250)
        type = models.CharField(max_length=20)
    
    
    # В settings.py делаем настройки для DRF
    REST_FRAMEWORK = {
        'DEFAULT_AUTHENTICATION_CLASSES': (
            'rest_framework.authentication.SessionAuthentication',  # Авторизация через сессии Django
        ),
        'DEFAULT_PERMISSION_CLASSES': [
            'rest_framework.permissions.DjangoObjectPermissions'  # Доступ к объектам через Django
        ],
        'DEFAULT_RENDERER_CLASSES': (
            'rest_framework.renderers.JSONRenderer',
            'rest_framework.renderers.BrowsableAPIRenderer',  # Если надо через браузер вручную удобно дёргать api
        )
    }
    
    # Создаем router и затем уже регистрируем его в urls.py
    from rest_framework import routers
    api_router = routers.DefaultRouter()
    
    from rest_framework import serializers, viewsets
    from rest_framework.decorators import list_route
    from rest_framework.filters import DjangoFilterBackend
    from rest_framework.response import Response
    
    
    # Делаем serializer
    class DocumentSerializer(serializers.ModelSerializer):
        class Meta:
            model = Document
    
        def validate_name(self, value):
            # Валидация отдельных полей
            if not value:
                raise serializers.ValidationError("Error")
            return value
    
        def validate(self, data):
            # Валидация на уровне объекта
            if not data.get('name', None):
                raise serializers.ValidationError("Error")
            return data
    
    
    # Делаем ViewSet (по сути форма)
    class DocumentViewSet(viewsets.ModelViewSet):
        serializer_class = DocumentSerializer
        # Если нужна возможность фильтрации
        filter_backends = (DjangoFilterBackend,)
        # Разрешаем фильтрацию только по отдельным полям
        filter_fields = ('name',)
        # Можно переопределить к каким объектам ViewSet будет предоставлять доступ
        queryset = Document.objects.all()
        # На этом собственно всё, если нужен только простой REST с поддержкой доступов Django
    
        # Если нужны свои методы в API для Document
        @list_route(permission_classes=[IsAuthenticated, ])  # permission_classes приведён для примера
        @permission_required_action(Document.make_some_permission)  # Об этом декораторе ниже
        def make_some(self, request):
            """
            @list_route означает, что метод будет доступен для всех Document (т.е. в нашем случае метод будет доступен
            по адресу /api/document/make_some), если нужен метод который будет доступен для конкретного объекта то
            надо использовать декоратор detail_route (метод будет доступен по адресу /api/document/1/make_some)
    
            Не забываем про доступы ... для list_route и detail_route модно задавать permission_classes и authentification_classes, о них в документации
            Чтобы проверить свой доступ Django для Document (созданный в Document.Meta) начинается цирк,
            т.к. встроенного механизма проверки такого доступа нет и надо либо делать свой MyCustomDocumentPersmissionClass унаследованный от BasePermission
            с реализацией has_permission и задавать его в permission_classes, либо делать проверку в коде метода make_some request.user.has_perm,
            либо адаптировать встроенный декторатор Django persmission_required (адаптировать надо потому, что декоратор рассчитан на function based view,
            а у нас метод класса который первым аргументом принимает self, моя реализация в конце в persmission_required_action).
            """
            try:
                result = Document.objects.filter(type='some')
            except Exception as e:
                # Ошибка, можно например вернуть произвольный JSON
                return Response({'result': 'error', 'msg': str(e)}, status=HTTP_500_INTERNAL_SERVER_ERROR)
            # Если надо вернуть массим объектов
            vs = DocumentViewSet(result, many=True)  # Может быть можно сам DocumentSerializer тут использовать, но так просто работает и проблем не доставляет
            return Response(vs.data)
    
        def get_permissions(self):
            # А ещё в ViewSet доступ можно проверить переопределив get_permissions ...
            from rest_framework.permissions import IsAuthenticated
            if self.action == 'make_some':
                return [IsAuthenticated(), ]
            return super().get_permissions()
    
    
    # Регистрируем ViewSet в router
    api_router.register('document', DocumentViewSet, base_name='document')
    
    # В urls.py регистрируем router
    
    urlpatterns = patterns('',
                           url(r'^api/', include(api_router.urls)),
                           )
    
    # Собственно всё
    
    """
    Вспомогательные вещи
    """
    
    from functools import wraps
    
    class classproperty(property):
        def __get__(self, cls, owner):
            return classmethod(self.fget).__get__(None, owner)()
    
    
    def permission_code(class_or_model, permission_name):
        if isinstance(class_or_model, ModelBase):
            return '{0}.{1}'.format(class_or_model._meta.app_label, permission_name)
        raise Exception('Не могу составить код для {0} {1}'.format(class_or_model, permission_name))
    
    
    from django.contrib.auth import REDIRECT_FIELD_NAME
    
    
    def user_passes_test_action(test_func, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME):
        def decorator(view_func):
            @wraps(view_func, assigned=available_attrs(view_func))
            # Тут первым параметром идёт self, а запрос уже вторым
            def _wrapped_view(object, request, *args, **kwargs):
                if test_func(request.user):
                    return view_func(object, request, *args, **kwargs)
                else:
                    raise PermissionDenied()
    
            return _wrapped_view
    
        return decorator
    
    
    def permission_required_action(perm, login_url=None, raise_exception=False):
        def check_perms(user):
            if not isinstance(perm, (list, tuple)):
                perms = (perm,)
            else:
                perms = perm
            # First check if the user has the permission (even anon users)
            if user.has_perms(perms):
                return True
            # In case the 403 handler should be called raise the exception
            if raise_exception:
                raise PermissionDenied
            # As the last resort, show the login form
            return False
    
        return user_passes_test_action(check_perms, login_url=login_url)
    Ответ написан
    Комментировать
  • Как отследить изменение в поле админки?

    @Sovetnikov
    технический директор pulsprodaj.ru
    1. В Django 1.8 в модели можно переопределить статичный метод from_db, который вызывается когда модель загружена из БД.
    В этот момент сохранять начальное значение свойства.
    2. До Django 1.8 начальное значение можно получать в __init__ модели.
    3. Зачитывать в pre_save сигнале объект из БД и делать сравнение с тем что у вас есть, но в БД тутп оявляется лишний запрос...

    Ешё учитывайте, что между тем как вы загрузили объект из БД и начинаете его сохранять, в БД его могли уже изменить ... п.3 с этим справится.
    Ответ написан
    Комментировать
  • Как визуализировать статистику потребления ресурсов контейнерами Docker?

    @Sovetnikov
    технический директор pulsprodaj.ru
    https://docker-py.readthedocs.io/en/1.2.2/api/
    from docker import Client
    cli = Client(base_url='tcp://127.0.0.1:2375')
    stats_obj = cli.stats('container-name')
    for stat in stats_obj:
        print(stat)
    Ответ написан
    Комментировать