• Как и когда выгодно покупать продукты JetBrains?

    miraage
    @miraage
    Старый прогер
    Тема повторяется из года в год.

    https://toster.ru/answer?answer_id=956226#answers_...


    Если работаете по найму и не можете себе позволить лицензию - попросите компанию ее Вам купить.
    500р/месяц в первый год, -20% за второй год, -40% в последующие, если подписка всё время активна - это совсем немного.

    Просто подумайте, сколько денег тратите в месяц на ненужную фигню, типа шоколадок/чипсов/сигарет. Сразу деньги на лицензию найдутся.
    Ответ написан
    Комментировать
  • Python-Django-Docker, как подключаться к докеру по локалхосту?

    fox_12
    @fox_12 Куратор тега Django
    Расставляю биты, управляю заряженными частицами
    docker-compose.yml:
    web: 
        ...
        links:
          - postgres
        env_file:  .env


    .env
    ...
    DB_HOST=postgres
    DB_PORT=5432


    тогда
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.postgresql_psycopg2',
             ...
            'HOST': os.environ.get('DB_HOST'),
            'PORT': os.environ.get('DB_PORT'),
        }
    }
    Ответ написан
    4 комментария
  • Как в Python 3 работает функция int()?

    Kademn
    @Kademn
    Злой
    Как в Python 3 работает функция int()?

    В первую очередь необходимо отметить, что int это встроенный класс, а не функция. Да, фактически его используют как функцию, и даже в документации его можно найти в разделе built-in funcitons, но технически это класс.

    print(a) возвращает None

    Вы переменной a присваиваете результат работы метода __init__, но этот метод никогда ничего не возвращает, он необходим, чтобы изменять состояние объекта у которого он был вызван. В самом вашем вопросе уже есть объяснение что и как работает.

    Так как правильно?

    a = 12
    a = int(12)
    a = int.__new__(int, 12)


    В каждом из этих трех случаев будут работать методы __new__ и __init__. Python так устроен, что у всех объектов есть эти методы, они вызываются самим интерпретатором и вам не нужно делать это самостоятельно.
    Сначала вызывается метод __new__, этот метод возвращает объект (только что созданный инстанс), и у этого объекта вызывается метод __init__.
    Ответ написан
    Комментировать
  • Как обуздать Django messages?

    winordie
    @winordie
    Лучшая документация -- исходники
    Давайте посмотрим как работает framework messages.

    https://github.com/django/django/blob/master/djang...
    def messages(request):
        return {
            'messages': get_messages(request),
            'DEFAULT_MESSAGE_LEVELS': DEFAULT_LEVELS,
        }
    ...
    def get_messages(request):
        if hasattr(request, '_messages'):
            return request._messages
        else:
            return []

    Так messages попадают на страницу. Т.е. они берутся из request._messages. Как же они туда попадают?

    https://github.com/django/django/blob/master/djang...
    class MessageMiddleware(MiddlewareMixin):
        def process_request(self, request):
            request._messages = default_storage(request)
    ...
    def default_storage(request):
        return import_string(settings.MESSAGE_STORAGE)(request)
    ...
    MESSAGE_STORAGE = 'django.contrib.messages.storage.fallback.FallbackStorage'

    Значит в request._messages у нас лежит FallbackStorage(request)

    Перейдем к нашему коду
    messages.error(request, 'Ваш диапазон дат занят для данного объекта.')

    Что тут происходит? Посмотрим:
    https://github.com/django/django/blob/master/djang...
    def error(request, message, extra_tags='', fail_silently=False):
        add_message(request, constants.ERROR, message, extra_tags=extra_tags,
                    fail_silently=fail_silently)
    ...
    def add_message(request, level, message, extra_tags='', fail_silently=False):
        if not isinstance(request, HttpRequest):
            raise TypeError("add_message() argument must be an HttpRequest object, "
                            "not '%s'." % request.__class__.__name__)
        if hasattr(request, '_messages'):
            return request._messages.add(level, message, extra_tags)  # *** THIS ***
        if not fail_silently:
            raise MessageFailure('You cannot add messages without installing '
                        'django.contrib.messages.middleware.MessageMiddleware')

    Ага, вызывается метод add знакомого нам объекта FallbackStorage.
    Ему передается в качестве параметров:
    - level = constants.ERROR = 40
    - message = 'Ваш диапазон дат занят для данного объекта.'
    - extra_tags = ''

    Посмотрим на этот метод
    https://github.com/django/django/blob/master/djang...
    def add(self, level, message, extra_tags=''):
            if not message:
                return
            level = int(level)
            if level < self.level:
                return
            # Add the message.
            self.added_new = True
            message = Message(level, message, extra_tags=extra_tags)
            self._queued_messages.append(message)
    ...
    def _get_level(self):
            if not hasattr(self, '_level'):
                self._level = getattr(settings, 'MESSAGE_LEVEL', constants.INFO)
            return self._level

    Из этого кода можно сделать вывод что сообщение попадает в очередь сообщений если его уровень более или равен тому который задан в settings.MESSAGE_LEVEL (по умолчанию = contants.INFO = 20)

    Таким образом чтобы добавлялись только наши сообщения необходимо:
    1) в settings.py установить
    # settings.py
    ...
    MY_SUPER_ERROR = 80
    MESSAGE_LEVEL = MY_SUPER_ERROR
    ...

    2) Во вью писать
    if not available_cars:
            carstoshow = None
            messages.add_message(request, settings.MY_SUPER_ERROR, 'Ваш диапазон дат занят для данного объекта.')
            return redirect('car_detail', pk=car_used_id)
    Ответ написан
    1 комментарий
  • Как поддерживать две версии приложения (платная и бесплатная)?

    onqu
    @onqu
    weasy
    Конечно, можно использовать 2 ветки, конечно, можно делать все в одной ветке и понатыкать везде #ifdef FOR_NISCHEBROD, FOR_REGULAR_CLIENT, FOR_RICH_ONE, конечно, можно расставить тэги, чтобы было проще искать эти места в будущем.

    Но, при увеличении объема логики придется прибегнуть к использованию шаманского бубна, ритуалу выстрела в свою ногу и мольбы праотцам. Добавлять/править логику в этих кусках будет очень непросто.

    Другой вариант.
    Делать приложение модульным, где основное приложение является лишь каркасом с базовой функциональностью, лежит в отдельной репе, тестируется отдельно от всего, и где модули это подключаемые расширения (Компоненты, DLC, LIB, Whatever), у которых есть API интерфейс для расширения функциональности основного приложения, и каждый лежит в своей репе.
    Более того, их можно будет тестировать, как вкупе, так и отдельно от основного приложения. При сборке указываем только требуемые расширения. Нэкст лэвэл - подключать расширения динамически, то есть без сборки с приложением.
    Ответ написан
    2 комментария
  • Что такое такое rest api?

    @eandr_67
    web-программист (*AMP, Go, JavaScript, вёрстка).
    API социальных сетей - это вполне типичные примеры реализации REST API.

    REST (RESTful) - это общие принципы организации взаимодействия приложения/сайта с сервером посредством протокола HTTP. Особенность REST в том, что сервер не запоминает состояние пользователя между запросами - в каждом запросе передаётся информация, идентифицирующая пользователя (например, token, полученный через OAuth-авторизацию) и все параметры, необходимые для выполнения операции.

    Всё взаимодействие с сервером сводится к 4 операциям (4 - это необходимый и достаточный минимум, в конкретной реализации типов операций может быть больше):
    1. получение данных с сервера (обычно в формате JSON, или XML)
    2. добавление новых данных на сервер
    3. модификация существующих данных на сервере
    4. удаление данных на сервере

    Операция получения данных не может приводить к изменению состояния сервера.

    Для каждого типа операции используется свой метод HTTP-запроса:
    1. получение - GET
    2. добавление - POST
    3. модификация - PUT
    4. удаление - DELETE

    Т.е. :

    GET-запрос /rest/users - получение информации о всех пользователях
    GET-запрос /rest/users/125 - получение информации о пользователе с id=125
    POST-запрос /rest/users - добавление нового пользователя
    PUT-запрос /rest/users/125 - изменение информации о пользователе с id=125
    DELETE-запрос /rest/users/125 - удаление пользователя с id=125
    Ответ написан
    20 комментариев