• Как правильно начать изучение django?

    alxpy
    @alxpy
    Я бы посоветовал учить дальше в такой последовательности:
    Питон: Читая Лутца, можно состариться ;-) Для начала прочтите Укус Питона и Погружение в Python 3 (да, учите сразу 3й питон). Лутца и потом можно полистать, по мере необходимости.
    Джанго: Документация: en | ru | форумы
    БД: Для старта вам хватит просто познакомиться с SQL и пройти уроки.
    Дополнительно:
    Прочитайте про такие уязвимости: XSS, CSRF, SQL injection и т.д.
    Еще гляньте flask (можете даже начать с него, а не с джанго) и tornado.
    Ответ написан
    Комментировать
  • Как реализовать корзину на django?

    @deliro
    1. Оформи код соответственно
    2. Модель херня. Научись О2М связям
    3. Стоит ли хранить корзины на бэкенде? Их хранят на бэкенде, когда любят спамить людей, бросивших корзины
    4. В коде
    basket = Basket.objects.filter(user=request.user, book=book).first()
        if not basket:
            basket = Basket(user=request.user, book=book)
            basket.quantity += 1
            basket.save()


    Ошибка

    Вот пример одной корзины, которую я делал несколько лет назад.

    basket.py
    from collections import UserDict
    
    from core.models import ProductOption, Product
    from .models import Item
    
    
    class Basket(UserDict):
        changed = False
    
        def add(self, quantity=0, option=None, set_=False):
            self.changed = True
            id_ = str(option.product.id)
            option = str(option.id)
            self.setdefault(id_, {})
            self[id_].setdefault(option, 0)
    
            if set_:
                self[id_][option] = quantity
            else:
                self[id_][option] += quantity
    
            if self[id_][option] <= 0:
                del self[id_][option]
                if not self[id_]:
                    del self[id_]
                return 0
            else:
                return self[id_][option]
    
        @property
        def total_count(self):
            return sum(x for product, options in self.items() for _, x in options.items())
    
        @property
        def total_price(self):
            prices = {str(id_): price for id_, price in
                      Product.objects.filter(id__in=self.keys()).values_list('id', 'price')}
            return sum(x * prices[product] for product, options in self.items() for _, x in options.items())
    
        def cost(self, option):
            price = option.product.price
            return self.count_option(option) * price
    
        def count_option(self, option):
            product_id = str(option.product.id)
            option_id = str(option.id)
            return self.get(product_id, {}).get(option_id, 0)
    
        def flush(self):
            self.changed = True
            for key in list(self):
                del self[key]
    
        def build_order(self, order):
            items = []
            for product_id, data in self.items():
                product = Product.objects.get(id=product_id)
    
                for option_id, quantity in data.items():
                    if quantity == 0:
                        continue
                    option = None
                    if option_id != '0':
                        option = ProductOption.objects.get(id=option_id)
                    items.append(
                        Item(order=order, option=option, quantity=quantity, product=product)
                    )
            order.items.bulk_create(items)
            self.flush()
            return order
    
        def fix(self):
            """Фиксит корзину на случай, если опции удалили, а они находятся в корзине"""
            ids = self.keys()
            exist_in_db = (Product.objects
                           .filter(id__in=ids, options__in_stock=True, options__show=True)
                           .values_list('id', flat=True))
            to_remove = set(ids) - set(str(x) for x in exist_in_db)
            for id_ in to_remove:
                del self[id_]
            if to_remove:
                self.changed = True
    
        def to_dict(self):
            return dict(self)

    middleware.py
    from django.utils.deprecation import MiddlewareMixin
    from .basket import Basket
    
    
    class BasketMiddleware(MiddlewareMixin):
        def process_request(self, request):
            request.basket = Basket(request.session.get('basket', {}))
    
        def process_response(self, request, response):
            if getattr(request, 'basket', None) is None:
                return response
            if request.basket.changed:
                request.session['basket'] = request.basket.to_dict()
                request.session.save()
            return response

    settings.py
    # ...
    SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'
    MIDDLEWARE_CLASSES = [
        # ...
        'orders.middleware.BasketMiddleware',
    ]
    # ...

    views.py
    @method_decorator(csrf_exempt, name='dispatch')
    class ChangeBasketOption(View):
        def post(self, request):
            change = int(request.POST.get('change'))
            pk = int(request.POST.get('id'))
            set_ = bool(request.POST.get('set', 0))
            option = get_object_or_404(ProductOption, pk=pk)
            value = request.basket.add(option=option, quantity=change, set_=set_)
            cost = request.basket.cost(option)
            return JsonResponse({
                'value': value,
                'cost': cost,
                'total': request.basket.total_price
            })
    
    
    class Basket(FormView):
        template_name = 'orders/basket.html'
        form_class = OrderForm
        success_url = reverse_lazy('ordered')
    
        def get(self, request, *args, **kwargs):
            request.basket.fix()
            return super().get(request, *args, **kwargs)
    
        def get_context_data(self, **kwargs):
            kwargs['products'] = Product.objects.filter(id__in=self.request.basket.keys())
            kwargs['can_order'] = self.request.basket.total_price >= min_order_cost()
            return super().get_context_data(**kwargs)
    
        def get_form_kwargs(self):
            kwargs = super().get_form_kwargs()
            kwargs['user'] = self.request.user
            return kwargs
    
        def form_valid(self, form):
            order = form.save()
            order = self.request.basket.build_order(order)
            mail_new_order(order)
            return super().form_valid(form)



    Смысл в том, что все корзины хранятся только в куках (из-за SESSION_ENGINE) у самих пользователей. Это означает, что хоть миллиард юзеров зайдёт и добавят по миллиону товаров — они не прибавят ни байта занимаемого места на HDD, пока не сделают заказ. К тому же, куки — очень быстрое хранилище и изменения в корзине происходят моментально. К примеру, AJAX запросы в ChangeBasketOption в среднем занимают 30мс в браузере.
    Ответ написан
    Комментировать
  • С чего начинать обучение backend-разработчику и какой минимум знаний нужен на junior'а в 2016-2017?

    Adamos
    @Adamos
    > информация укладывается неструктурировано, отрывками, а хотелось бы, чтобы в голове все было разложено "по полочкам"

    Не существует курса обучения программированию, который раскладывает все по полочкам сразу, в теории. А если и есть - то он не работает.
    Чтобы действительно разложить IT-знания по полочкам, нужны годы практического опыта.
    Поэтому - погружаться и учить то, что получается изучить. Сразу пробуя то, что получается пробовать. А потом - переучиваться, с ужасом оглядываясь на то, что было сделано год назад. Потому что пришел опыт, и начался новый уровень сложности...
    Ответ написан
    Комментировать
  • Как развить программистское мышление?

    zhukpavel
    @zhukpavel
    Готов поспорить, что вы после прочтения задачи сразу же садитесь писать код, что является абсолютно не верным подходом, так как в голове еще нет сформированного решения и его приходится придумывать на ходу. Непродуманная структура программы ведет в множеству ошибок, а в случае отсутствия опыта, как у вас - вообще заводит в тупик.

    Я бы советовал вам такой способ, опробованный на себе:
    1. Придумать и записать на бумаге алгоритм решения задачи. На человеческом языке, разбив по пунктам. Причем под пунктом понимается некоторая более простая подзадача, которая на данном этапе не важно как решается.
    2. Повторять пункт 1 для каждой подзадачи до тех пор, пока решение очередной подзадачи не станет очевидным.
    3. Записать каждую подзадачу отдельно на листке в терминах языка программирования. Начиная от самых мелких и постепенно придя к исходной.
    4. (первые три пункта выполняются на листке бумаги с карандашом) И вот только теперь, с полным пониманием происходящего, можно начинать писать код.

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

    По поводу гугления. В общем - это полезный навык для программиста, но явно не на этапе "начал с полного нуля". Сейчас главное научиться декомпозировать задачи и строить алгоритмы. Единственное зачем сейчас можно(и даже нужно!) залазить в гугл - это официальная документация по Java.
    Ответ написан
    Комментировать
  • Как научиться решать задачи?

    @Dum_spiro_spero
    Постановка слишком общая.
    Какие задачи кстати? По физике? По математике? По жизни?
    " совсем плохо ... ориентируюсь в новых, ранее незнакомых задачах".
    Ну так это у всех так.
    На мой взгляд - надо развиваться ВШИРЬ. С эрудицией приходит возможность связывать задачи из разных областей и находить аналогии.
    В качестве рецепта могу порекомендовать бессистемное чтение журнала "Квант".
    Ответ написан
    1 комментарий
  • Как сделать документацию к коду?

    @kn0ckn0ck
    Продюсер
    Есть две крайности, которых лучше избегать:
    1. красивая и исчерпывающая документация требует колоссальных ресурсов на поддержку
    2. сложно воспринимаемый код, без малейших подсказок с чего все начинается и чем заканчивается

    Стандартные решения:
    1. самодокументируемый код, составленный так, что читающий может понять что для чего и в какой последовательности работает.
    2. описание интерфейсов (назначение метода, тип/суть параметров и т.п.) в форме комментов в коде.
    3. автоматическая документация (генерится из комментариев) - эффективно, только если сам код закрыт.
    4. модульные тесты, фиксирующие требования к коду и демонстрирующие его использование.
    5. описание высокоуровневого дизайна (High Level Design, HLD), описывающий какие элементы существуют, их взаимосвязь друг с другом и основные сценарии взаимодействия.

    Работающая документация - это компромисс из этих практик, релевантный конкретной ситуации.

    Кстати, проектная работа, это не только документация к коду, это еще и свод правил, которые позволят архитектуре не расползтись кто в лес кто по дрова, а также сохранят стилистику написания кода для единообразия и легкой поддерживаемости кода.
    Ответ написан
    12 комментариев
  • Что такое нормализация базы данных простыми словами?

    sarapinit
    @sarapinit
    Точу водой камень
    БД нужна чтобы хранить утверждения о состоянии информационной системы.
    Ситуацию в которой утверждений о состоянии какой-то части системы больше чем одно мы считаем дублированием информации. (У вас эта ситуация называется "избыточность").
    Если есть дублирование информации, то возможна ситуация когда утверждения могут противоречить друг другу. В этом случае БД неконсистентна и информационная система может работать некорректна.
    Нормализация БД - устранение дублирования информации в БД с целью достижения консистентности, в первую очередь. Нормальные формы - это шаги которые нужно пройти на пути к консистентности (делай раз, делай два ...)
    Побочным эффектом нормализации является уменьшение размера БД.
    В случаях когда производительность важнее консистентности, выполняют денормализацию БД (внесение избыточности) под определённые запросы, чтобы избежать объединений таблиц (JOIN).
    Ответ написан
    2 комментария
  • Что работает лучше: $3 vs $2.99?

    AleksandrB
    @AleksandrB
    Совсем недавно вывел "Hello world"
    Не знаю что там на счет исследований, но если 90% компаний это использует, может, это и работает.
    Ответ написан
    Комментировать
  • Как убедить начальство отказаться от велосипедов?

    evnuh
    @evnuh
    Поиск Гугл помог мне, впусти и ты его в свой дом
    Не волнуйтесь, вас уволят и правильно сделают. И вот почему.
    Начну со стороны хорошего бизнесмена:
    У него уже есть cms и crm, которую он пилил 5 лет, умеет продавать и знает. Да, так получилось, свой велосипед, ужасно написанный, но это его не волнует до тех пор, пока она кормит и его и всех его подопечных. Отказаться от неё означает не только огромные временные затраты на смену всего, начиная от обучения программистов как её пилить, заканчивая обучением всех, кто будет её касаться. Так же это означает поддержка уже двух систем, старых клиентов со старой и новых с новой. Но самое главное - это высокий риск того, что продавать её будет тяжелее.

    Со стороны хорошего разработчика:
    А хорошему разработчику вообще до фени, с чем ему работать. Спросите у опытных. Эмоционировать при виде говнокода и велосипедов - это максимализм юного программиста. Разработчики с опытом умеют погружаться в любой велосипед, в любой говнокод и работать с ним. А потому что они уже навидались и в своё время тоже кричали и пытались перевернуть мир, но, кому это надо? Вы - наёмный работник, вы не должны писать красивый код, вы должны решать бизнес задачи. Бывалые так и делают, просто иногда про себя вздыхая, т.к. чувство прекрасного всё же не убить :)
    Ответ написан
    18 комментариев
  • Полезно ли при обучении изобретать велосипеды?

    @ProFM
    Конечно полезно, и забудь про "велосипеды и велосипедистов", кто про это говорит, сам не понимает ничего в этом. Хороший продукт тот, который созданный тобой, а не кем то
    Ответ написан
    Комментировать
  • Как разбираться в спецификациях RFC?

    Zoominger
    @Zoominger
    System Integrator
    Что такое спецификация (я гуглил, но так и не понял чем отличается от документации)?

    Считайте их аналогом ГОСТа. Это набор правил и инструкций, которые определяют ту или иную систему.

    Как вы работаете с RFC?

    Беру да вдумчиво читаю.
    Ответ написан
    2 комментария
  • Какие типовые задачи решаются через middleware django?

    @deliro
    1. Идентификация пользователя. Например, кастомная аутентификация или навешивание каких-нибудь перманентных куков
    2. Сессии
    3. Логгирование ответов/запросов
    4. Ограничение доступа к множеству URL'ов с определённым префиксом
    5. Инъекции в HTML-ответ

    Что удалось придумать за минуту
    Ответ написан
    3 комментария
  • Документация Django?

    flygrounder
    @flygrounder
    Python/Django
    Нет, не устарела. Но только после неё следует почитать про фишки новых релизов. Например про path из 2.0 https://docs.djangoproject.com/id/2.0/releases/2.0...
    Ответ написан
    1 комментарий
  • Как запомнить классы, функции и методы в программировании и сэкономить время?

    Rou1997
    @Rou1997
    А я головой думал.
    Нет никакого смысла запоминать классы, функции и методы, мозг человека - это аналоговый компьютер, поэтому ему в разы тяжелее запомнить "сырые" байты, чем цифровым, таким, как сервера Google и т.п., и умещается их меньше, срабатывает "сборка мусора", забываете.
    Кесарю - кесарево, а аналоговому компьютеру - аналоговые данные, то есть абстрактные образы, например: "чтобы передать данные по сети, нужно сделать POST-запрос, а чтобы получить - нужен GET-запрос", "оба типа запросов являются HTTP-запросами, поэтому понадобится библиотека для работы с HTTP".
    Такие "логические" образы, очевидно, формируются только в процессе реализации задач, а не "зубрения" теории, "зубрение" - это опять "сырые" байты, неэффективно, а использование нескольких языков, очевидно, ускоряет их формирование.
    Еще во многих случаях есть смысл писать Utils/Helpers, почитайте, что это такое.
    Ответ написан
    Комментировать
  • Когда применять migrate и makemigrations?

    @MAGistr_MTM
    Учусь программировать
    Нужно делать миграции, когда изменил поле в модели(не инстанса модели). И после сделанных миграций, бажано их применить.
    Ответ написан
    2 комментария
  • Как поставить Шведское время в Django?

    @MAGistr_MTM
    Учусь программировать
    from django.utils import timezone
    
    now = timezone.now()

    ПС. такое гуглится оч быстро и просто
    Ответ написан
    Комментировать
  • Как выучить основные методы и функции Javascript?

    trevoga_su
    @trevoga_su
    не надо учить язык, точнее не надо заучивать ВСЕ его методы/функции.
    надо знать хорошо синтаксис языка и понимать как на нем писать.

    достаточно пройтись 2-3 раза по мануалу глазами и понять, что он умеет и какие базовые методы в нем есть.
    потом когда возникает задача, например найти функцию какую-то, открываем мануал и читаем.
    это применимо ко всем ЯП
    Ответ написан
    4 комментария
  • Почему темнеет экран монитора?

    @CubixSystem
    Если видео от интела, то уберите галку здесь - внезапно она влияет на регулировку контраста и при работе от сети.
    5db90c2fe0454dd790a5602dc34c0562.png

    И еще посмотрите здесь
    7fc73695c5e24c66bee9f7e4bbe6ccfc.png
    Ответ написан
    Комментировать
  • Термин для слова "говнокод"?

    slaum
    @slaum
    Часто называют «индусский код»
    Ответ написан
    Комментировать
  • Термин для слова "говнокод"?

    vinxru
    @vinxru
    Говнокод — это код не похожий на код оппонента. Понять чужой код — это долгая и нудная работа. А если код написан так, как будто ты его написал, то ты его понимаешь и это экономит время на доработку и отладку.

    Любой начинающий программист первым делом бросается переписывать чужие программы. Даже если они абсолютно работоспособны, даже если после переписывания пропадет часть функционала и появятся баги.

    Это сказано с долей юмора конечно.

    Говнокод — это применение не самых лучших (с точки зрения большинства) решений проблемы. Ну к примеру говнокодом назовут выход из цикла установкой счетчика в максимальное значение.

    for(i=0; i<1000; i++)
      i=INT_MAX;
    


    Это полностью работоспособное решение, не тормозное, не громоздкое. Но лучше применять для этих целей break. Потому что так все привыкли. Так же говнокодом является повторение функционала стандартной библиотеки, например string или auto_ptr. А так же структура (архитектура) программы, отличная от любимой у оппонента. Например, не использование MVC при разработке программы.

    К примеру, я использую конструкцию:

    void main() {
      // ...
      void init_dialog();           init_dialog();
      void init_referenceControl(); init_referenceControl();
      void init_functionsHelp();    init_functionsHelp();
      void init_new_style();        init_new_style();
      // ...
    }
    </souce>
    
    Вместо определения функций в .H файлах, я это сделал прямо на месте. Говнокод. Можно было бы создать кучу .H файлов, использовать одну из множества библиотек выполняющих инициализацию. Но это максимально простой способ, способ без использования доп классов, функций и программ; так легче отлаживать, так наглядно изображена последовательность инициализации, так не надо писать кучу #include, и кроме функции MAIN, функции инициализации ни от куда не вызвать.
    
    Говнокод - потому что люди бы не так написали.
    Ответ написан
    3 комментария