Django ManyToMany с двумя полями через промежуточную модель
Пишу код переноса товаров из корзины в заказы. Все работает корректно, но вот как в админке отображается мне не нравится.
Если конкретно, то вся заморочка в том, что я не могу в заказах просто воспользоваться ManyToMany связью с Товарами Product(), потому что в Корзине Basket() есть параметр Сколько шт. count
Как это работает:
- Достаем из БД корзину пользователя
- Создаем объект Заказов
Order() - Пробегаемся по Корзине
Basket()- Каждый продукт из корзины сохраняем вместе с
countв моделиPurchase() - В объекте Заказов
Order()есть M2M связь сPurchase(). Вот туда новую записьPurchase()и приклеиваем
- Каждый продукт из корзины сохраняем вместе с
views.py:
class OrdersLocation(View):
"""Заказы пользователя"""
def post(self, request):
"""Оформить заказ всех продуктов из корзины"""
# Получаем пользователя с его корзиной
user = User.objects.filter(id=request.user.id).first()
basket = Basket.objects.filter(user=user).all()
# Делаем новый заказ
purchases = []
for wont in basket:
p = Purchase(product=wont.product, count=wont.count)
p.save()
purchases.append(p)
order = Order(user=user)
order.save()
for _ in purchases:
order.products.add(_)
order.save()
# Очищаем корзину
for wont in basket:
wont.delete()
return redirect('store:orders')
models.py:
class Basket(models.Model):
"""Корзина"""
user = models.ForeignKey(User, related_name='Пользователь', default=0, editable=False, on_delete=models.CASCADE)
product = models.ForeignKey(Product, related_name='Товар', default=0, on_delete=models.CASCADE)
count = models.IntegerField('Сколько шт.', default=1, auto_created=True)
ctime = models.DateTimeField('Запись создана', default=timezone.now)
def __str__(self):
return '{} заказал {} в количестве {} штук' \
''.format(self.user_id, self.product.caption, self.count)
class Meta:
verbose_name = 'Продукт'
verbose_name_plural = 'Корзина'
class Purchase(models.Model):
"""Экземпляр заказа"""
product = models.ForeignKey(Product, default=0, editable=False, on_delete=models.CASCADE)
count = models.IntegerField('Сколько шт.', default=1, auto_created=True)
ctime = models.DateTimeField('Запись создана', default=timezone.now)
def __str__(self):
return 'Заказ {} в количестве {} шт.' \
''.format(self.product.caption, self.count)
class Meta:
verbose_name = 'Заказанный продукт'
verbose_name_plural = 'Заказанные продукты'
class Order(models.Model):
"""Заказы"""
user = models.ForeignKey(User, default=0, editable=False, on_delete=models.CASCADE)
products = models.ManyToManyField(Purchase, verbose_name='Заказанные продукты')
status = models.CharField('Статус', max_length=13, choices=(
('Подтверждение', 'Подтверждение'),
('Отправка', 'В очереди на отправку'),
('Доставка', 'Доставка'),
('Доставлен', 'Заказ доставлен'),
('Отменено', 'Отменено'),
), null=True, default='Подтверждение')
ctime = models.DateTimeField('Запись создана', default=timezone.now)
def __str__(self):
return 'Заказ {} №{}' \
''.format(self.user.username, self.id)
class Meta:
verbose_name = 'Заказ'
verbose_name_plural = 'Заказы'
Результат ужасает
Вопрос: как сделать так, чтобы администратор сайта мог менять состав заказа: добавлять/удалять товары и указывать через админ-панель количество экземпляров?
Сейчас ситуация такова, что каждый раз создается запись Purchase() из товара и количества шт. и вот из них и выбирай. На лету нужную запись не создать, как быть?
