Django работа с моделями и логикой

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

class Product(models.Model):
   title = models.CharField('Название', max_length=250)
   item = models.ManyToManyField('ItemProduct',blank=True,verbose_name='Предмет продукта')
class ItemProduct(model.Model):
   title = models.CharField('Название', max_length=250)
   item = models.TextField('Продукт')
class Profile(models.Model):
   """ Профиль пользователя """
   user = models.OneToOneField(User, on_delete=models.CASCADE, verbose_name="Пользователь")
   orders = models.ManyToManyField(ItemProduct, blank=True, verbose_name='Покупки')  

Это пример моделей.
Логика: У меня есть Product в нем лежит множество (5 шт, 6 шт и т.д.) ItemProduct. Мне нужно отсоединить связь от Product и присоединить к Profile. То есть человек покупает Windows key и у него в профиле появляется строчка (ItemProduct --> title). При этом связь между Product и ItemProduct разорвана, для того чтобы человек не мог купить эти же модели.
Если надо изменить модели, то приведите пример (какая связь и между чем).


Ответы (1 шт):

Автор решения: Za Ars

Я бы заменил связи с MenyToMeny на ForeignKey (перенести поля из Product и Profile в ItemProduct) указав related_name. Таким образом у вас будет 1 ключ, связанный только с 1 объектом.

А чтобы после покупки ключ исчезал из вариантов покупки, в save методе или pre_save сигнале, если пользователь указан (купили товар), убираете связь у ItemProduct (product=None) например.

class Product(models.Model):
   title = models.CharField('Название', max_length=250)



class Profile(models.Model):
   """ Профиль пользователя """
   user = models.OneToOneField(User, on_delete=models.CASCADE, verbose_name="Пользователь")


class ItemProduct(model.Model):
   title = models.CharField('Название', max_length=250)
   item = models.TextField('Продукт')
   product = models.ForeignKey(to=Product, on_delete=models.CASCADE, related_name='items', blank=True, null=True,)
   user = models.ForeignKey(to=Profile, on_delete=models.CASCADE, related_name='orders', blank=True, null=True,)

    # Вариант 1
    def save(self, *args, **kwargs):
        if self.user and self.product:
            self.product = None
        return super().save(*args, **kwargs)



# Вариант 2
@pre_save(.......)
def item_product_pre_save(sender, instance, **kwargs):
    if sender == ItemProduct:
        if instance.user and instance.product:
            instance.product = None

Обращаться к ItemProduct из других моделей в данном примере можно так:

  • Product - product_obj.items.all(), Product.objects.filter(items__title='....')
  • Profile - profile_obj.items.all(), Profile.objects.filter(orders__title='....')
→ Ссылка