• Как правильно спроектировать товары с вариантами?

    @mr_drinkens89 Автор вопроса
    sim3x, так руководство решило. У джинс родитель "Одежда". Не совсем логично, но, ничего не поделать.
    Просто я думал сперва, что можно обойтись лишь FK к категории. Но, товар может находиться в любой категории выше по дереву. Соответственно, тут только m2m к категории, насколько я понимаю.
  • Как правильно спроектировать товары с вариантами?

    @mr_drinkens89 Автор вопроса
    sim3x, добрый день) вновь задался вопросом со структурой и верностью его создания в своем интернет-магазине.
    По поводу подвариантов товаров - разобрался. Вроде бы все ок работает, но, возникают сложности при добавлении функционала или расширении.
    По структуре, в магазе следующий вид: "мужчинам", "женщинам". Далее, идут главные категории "Обувь, одежда", ну и сабкатегории (джинсы, брюки).
    Такой вопрос: делать ли мне отдельно модель "коллекции" ("мужчинам/женщинам"), потом модель "ПодТипы ("Одежда, Обувь") и в конце - категории ("Джинсы, брюки"). Или же можно оставить все в одной модели Category?(MPTT)
    Каждый товар, если он находится "в последней" категории - может находиться и в категории выше (То есть если джинсы "Гуччи" находятся в джинсах, то они также есть и в "Верхней одежде" и в "Мужчинах").
    Помнится, был разговор по поводу тегов, что можно добавить поле "тег" в товар, и пихать туда категории.

    Какая схема более рациональна и проста?
    Сейчас юзаю MPTT (чтобы дерево нарисовать), ну и вид товара такой (кусок):
    class Category(MPTTModel, SeoModel):
        name = models.CharField("Название категории", max_length=250)
        slug = AutoSlugField("Slug", unique=True, populate_from='name', always_update=False, max_length=255, editable=True)
        parent = models.ForeignKey("self", verbose_name="Родительская категория", blank=True, null=True
        description = MarkdownxField("Описание", blank=True)
        display = models.BooleanField("Показывать", default=True)
    
    
    class Product(SeoModel):
        sku = models.CharField('Артикул', max_length=250, help_text='Объединияет между собой все варианты воедино')
        color = models.ForeignKey(Color, verbose_name='Оригинальный цвет (из файла резерва)', blank=True, null=True, on_delete=models.SET_NULL)
    
        name = models.CharField('Название', blank=True, max_length=350)
        slug = AutoSlugField("Уникальная ссылка", slugify=custom_slugify, unique=True, populate_from='name', editable=True)
    
        category = models.ManyToManyField(Category,verbose_name='Категория',blank=True,null=True,related_name='my_category')
        brend = models.ForeignKey(Brend, verbose_name='Бренд',blank=True,null=True, on_delete=models.SET_NULL)


    спасибо
  • Схема уведомлений пользователя в определенное время?

    @mr_drinkens89 Автор вопроса
    Сергей Горностаев, На клиенте сделано так: настроена центрифуга (centrifugo), которая соединяется с клиентом через сокет. Далее, на бекенде слушаю post_save сигнал от модели Notifications, и рассылаю это в центрифугу. То есть проблем доставки до клиента нет, основная сложность - это "вовремя" сделать эти уведомления, не прибегая к постоянным опросам БД.
  • Схема уведомлений пользователя в определенное время?

    @mr_drinkens89 Автор вопроса
    Сергей Горностаев, насколько я понял из документации, в celery можно выставлять задачи на определенное время. То есть юзер создает событие - выставляет время - вьюшка обрабатывает запрос и ставит в очередь celery task по специфичному времени в будущем.
    Далее, в назначенное время срабатывает task и юзеру летит нужное ему уведомление (если он онлайн). Если нет - то уведомление будет у него в истории уведомлений.

    Правильно ли я понял предложенную Вами схему?
  • Схема уведомлений пользователя в определенное время?

    @mr_drinkens89 Автор вопроса
    Сергей Горностаев, насколько я понимаю, задание будет храниться в памяти? (celery+redis). Насколько надежно данное решение? Плюс, необходимо как-то сохранять уведомление, дабы у юзера была некая "история уведомлений".
  • Схема уведомлений пользователя в определенное время?

    @mr_drinkens89 Автор вопроса
    Сергей Горностаев, пользователь ставит в своем веб-календаре (alert time). То есть у пользователя есть свой "календарь" на клиенте, куда он вбивает события и ставит время уведомления об этом событии (если необходимо).
  • Как правильно подключить centrifugo в React-Redux?

    @mr_drinkens89
    Добрый день.
    Удалось ли решить проблему? Если да, то подскажите, каким образом получилось сделать коннект?
    спасибо
  • Как закрыть все поповеры и инпуты?

    @mr_drinkens89
    KnightForce: react+redux) хотя б кратко, как это будет выглядеть)
    спасибо.
  • Как правильно сделать initialState в redux?

    @mr_drinkens89 Автор вопроса
    Антон Мудренок: Благодарю за помощь, разобрался теперь по этому моменту)
  • Как правильно сделать initialState в redux?

    @mr_drinkens89 Автор вопроса
    Антон Мудренок: понятно, что если это будет описано в одном редьюсере - то да, после первого return обработка прекратится.
    Но, мы описываем все это дело в разных редьюсерах и каждый "забирает" только свою ветку и выплевывает в стор только свою часть))
  • Как правильно сделать initialState в redux?

    @mr_drinkens89 Автор вопроса
    Антон Мудренок: необходимо как-то упростить все это дело, и не выходить за рамки редакс.
    В том пример выше, что вы указали, как я понимаю, все равно изменение стора идет через редьюсер?
    Может быть я не так описал, но стор сейчас заполнился данными с сервера по той схеме, что я описал.
    Мы пишем все эти "FETCH_ALL" в разных редьюсерах, и каждый обрабатывает их по своему. В чем здесь не так?) (я скопировал код из разных редьюсеров)
  • Как правильно сделать initialState в redux?

    @mr_drinkens89 Автор вопроса
    Антон Мудренок: Супер)
    Немного упростил для себя.
    в componentWillMount я вызываю dispatch и передаю action. Далее, в action делаю запрос к серверу и тащу эти первоначальные данные.
    Ну и в каждом редьюсере (boards ,lists, tasks) "слушаю" FETCH_ALL. Ну и выдаю нужную ветку:
    if (action.type === 'FETCH_ALL') {
        return action.data.boards;
      }
    if (action.type === 'FETCH_ALL') {
        return action.data.lists
      }
    if (action.type === 'FETCH_ALL') {
        return action.data.tasks;
      }


    сейчас стейт заполнен данными с сервера.
    Единственное, они подаются не прям на вход, а когда уже рут-компонент грузится.
  • Как правильно сделать initialState в redux?

    @mr_drinkens89 Автор вопроса
    Антон Мудренок: да, схема всегда будет такая)
    Суть всего: приложение "ворочает" доски, у досок есть списки, а у списков - задачи)
    На сервере я настроил, что при первоначальном запуске аппа - выдает нам JSON, который содержит в себе:
    boards:[объекты-доски] ,
    lists:[объекты-списки],
    tasks:[объекты-таски]


    Как я понимаю, суть редакса в том, что мы всегда имеем одно текущее состояние (по сути, json). Дак вот, я хочу, чтобы в момент запуска приложения все текущие объекты для данного юзера (вообще все), подгрузились с сервера и хранились в STORE.
    Ну а уже далее, например при клике на определенную доску, мне уже не надо будет делать запрос, а я с помощью filter выберу нужные мне листы и задачи.
    Надо, чтобы при createStore (например), мы уже передали бы приложению наш начальный json - который и придет с сервера.

    Не пойму, что не так идет) Либо, можно, конечно, сделать так: добавить редьюсер, назвать его как-нить "root", и он и будет возвращать нам текущее состояние.
    Но, как я понимаю, оно будет в виде:
    root:
      boards:[],
      lists:[],
      tasks:[],

    то есть имеем еще один уровень вложенности, так как каждый редьюсер призван обрабатывать только свою, определенную ветку из всего стора)
  • Как правильно сделать initialState в redux?

    @mr_drinkens89 Автор вопроса
    Антон Мудренок: да, это ок.
    Я не пойму, почему ответ уходит не в "глобальный вид стейта", а заменяет какую-то его часть?
    Понимаю, что каждый редьюсер разбивает стейт и берет свою часть для обработки.
    Но, таким образом, если мне с сервера приходит все (boards,lists,tasks), как мне разово обновить стейт (глобально)?
  • Как правильно сделать initialState в redux?

    @mr_drinkens89 Автор вопроса
    Вот редюьсер, в котором я обрабатываю ответ:
    FETCH_ALL - получение начальных значений с сервера.

    export default function lists(state = {}, action){
      
      if (action.type === 'FETCH_ALL') {
        return action.data
      }
      if (action.type === 'GET_LISTS') {
        return action.data
      }
    
      if (action.type === 'INSERT_LIST') {
        return [
          ...state,action.data
        ];
      }
    
      if (action.type === 'CHANGE_LIST') {
        return state.filter(element => element.is_delete == false )
      }
    
    	return state;
    }


    А ответ с сервера приходит в виде:
    {
    boards:[объект1,объект2],
    lists:[объект1,объект2],
    tasks:[объект1,объект2],
    }
  • Как правильно сделать initialState в redux?

    @mr_drinkens89 Автор вопроса
    Антон Мудренок: все равно не то что-то выходит, прелоад заполняется не в том месте (скрин)
    Быть может, все-таки уйти от combineReducers и использовать один?
    Либо, заюзать https://www.npmjs.com/package/redux-async-initial-state

    777e6f7ecb2247dd912b59ba09623c13.png
  • Как правильно сделать initialState в redux?

    @mr_drinkens89 Автор вопроса
    Антон Мудренок: Благодарю)
    redux-thunk установлен, да. еще юзаю axios для упрощения написания запросов.
    Видимо, вот это store.dispatch(getAllProducts())
    и будет решением). Так как сейчас combineReducers делает уже именнованные объекты (ключ - название редьюсера).
    То есть сейчас я при вызове метода, делаю запрос и ответ уходит в этот именнованный редьюсер preload.
    Думал, уж убирать этот combineReducer, и использовать один общий - тогда проблема бы решилась. Но, думаю, это не лучшее решение и не выходи из ситуации.
  • Как правильно сделать initialState в redux?

    @mr_drinkens89 Автор вопроса
    Антон Мудренок: получается, что initialState (предзагрузка данными) будет не в связке с редакс? то есть это тупо аяксовый запрос?
    Как создать initialData я понял.
    То есть, суть какая: я предварительно записываю так:
    const initialData = {
      boards:[],
      lists:[],
      tasks:[]
    }

    и вставляю это в createStore - ОК.
    далее, наше приложение "грузится", и нам надо этот объект заполнить.
    Если идти через схему: действие-редьюсер-изменение стора, то, ничего не выйдет?
    Вот мой индекс-редьюсер:
    export default combineReducers({
    	preload,
    	boards :boards,
    	lists  :lists,
    	tasks  :tasks
    })


    preload - типа как делает предзагрузку.
    но, если я сделаю эту предзагрузку в preload, то и объекты будут именно в нем?
    Прошу прощения, если объясняю как-то не так)
    Можно ли какой-то банальный пример?

    Сейчас выходит так:
    (стейт из девтулс):
    {
    preload:{boards:[object,object,],lists:[object,object,]tasks:[object,object,]},
    boards:[],
    lists:[],
    tasks:[]
    }
  • Как правильно сделать initialState в redux?

    @mr_drinkens89 Автор вопроса
    с сервера мне приходит сразу "все". (сперва делаю предазгрузку объектов, а после - уже ворочаю их на клиенте- не знаю, правда, насколько это верный подход).
    я создал initialData:
    const initialData = {
      boards:[],
      lists:[],
      tasks:[]
    }
    
    const store = createStore(reducer, initialData, composeWithDevTools(applyMiddleware(thunk)));


    далее, я имею комбинацию редьюсеров вида:
    export default combineReducers({
    	boards :boards,
    	lists  :lists,
    	tasks  :tasks
    })


    Можно ли (хотя б кратко) описать, каким образом сделать "предзагрузку"?
    Ведь все должно идти через редьюсер, как я понимаю:
    componentWillMount - action - начальный редьюсер, который заполнил начальный store.

    спасибо