Relationship Django Models

Asked

Viewed 1,038 times

0

I have a model called Item and made a call Compra. I was able to relate several items with each purchase, but I don’t know how to relate the quantity of each item in each purchase.

class Item(models.Model):
nome = models.CharField('Nome', max_length=100, null=False, unique=True)
estoque = models.PositiveIntegerField('Estoque', blank=False, default=0)
estoque_min = models.PositiveIntegerField('Estoque Min', blank=False, default=0)
slug = models.SlugField('Atalho')

def __str__(self):
    return self.nome

Model Compra:

class Compra(models.Model):
fornecedor = models.ForeignKey(Fornecedor, verbose_name='Fornecedor', on_delete=models.CASCADE)
item = models.ManyToManyField(Item, verbose_name='Item', related_name='Itens')
data_compra = models.DateTimeField('Data de Compra', auto_now=True)
data_entrega = models.DateTimeField('Data de Entrega')
entregue = models.BooleanField('Entregue', default=False)

def get_absolute_url(self):
    return ('compras/' + str(self.pk))

I made a relationship Many-to-Many with the items, in Django Admin was like this:

Django Admin

I wanted a suggestion of what logic to use to put quantity in each selected item, being this quantity related to each purchase, and not to the item stock.

EDIT: I used the through and it worked, but the problem is another.

def compras_detalhe(request, pk):
compras = Compra.objects.all().filter(id=pk)

itens = []
for compra in compras:
    for item in compra.itens.all():
        print(item)
        itens.append(item)

With this code I can display the items that were purchased, but I can’t access the quantity field, which is in the Itemcompra model (intermediate through).

class Compra(models.Model):
fornecedor = models.ForeignKey(Fornecedor, verbose_name='Fornecedor', on_delete=models.CASCADE)
itens = models.ManyToManyField(Item, through='ItemCompra')
cliente = models.ForeignKey(Cliente, verbose_name='Cliente', on_delete=models.CASCADE)
data_compra = models.DateTimeField('Data de Compra', auto_now=True)
data_entrega = models.DateTimeField('Data de Entrega')
nota_fiscal = models.CharField('Nota Fiscal', max_length=100, default='-')
entregue = models.BooleanField('Entregue', default=False)

def get_absolute_url(self):
    return ('compras/' + str(self.pk))

class ItemCompra(models.Model):
item = models.ForeignKey(Item, verbose_name='Item', related_name='Itens', on_delete=models.CASCADE)
quantidade = models.IntegerField('Quantidade', default=0)
compra_id = models.ForeignKey(Compra, on_delete=models.CASCADE, related_name='Compra', null=True)

def __str__(self):
    return (self.item.nome + str(self.quantidade))

class Item(models.Model):
    nome = models.CharField('Nome', max_length=100, null=False, unique=True)
    unidade = models.ForeignKey(Unidade, verbose_name='Unidade', on_delete=models.CASCADE)
    estoque = models.PositiveIntegerField('Estoque', blank=False, default=0)
    estoque_min = models.PositiveIntegerField('Estoque Min', blank=False, default=0)
    slug = models.SlugField('Atalho')

    def __str__(self):
        return self.nome
  • You need another relationship: CompraItem, which relates the item to the purchase possessing the quantity. A Compra has one or more CompraItem, which is associated with a Item.

  • Ah, I get it, it makes sense thank you very much.

  • Remember that you will have to save most of the data of the items in the table CompraItem. Because when the purchase is made, data such as price must be saved separately, otherwise all purchases will become invalid when someone needs to update the prices of the items. Ex: I buy an item for 2 money and next year the price is readjusted for 3 money. The account that has already been paid cannot have this change, only for new purchases.

1 answer

0


Use the parameter through of ManyToManyField to define a model that will serve as connection between the other two. In this model you can put additional data:

class Item(models.Model):
    nome = models.CharField('Nome', max_length=100, null=False, unique=True)

class Compra(models.Model):
    item = models.ManyToManyField(Item, verbose_name='Item', 
        related_name='Itens', through='ItemCompra')
    data_compra = models.DateTimeField('Data de Compra', auto_now=True)

class ItemCompra(models.Model):
    item = models.ForeignKey(Item)
    compra = models.ForeignKey(Compra)
    qtd = models.PositiveIntegerField()
  • Quick doubt: when I select the items of the purchase I get an object Item or an object ItemCompra (or some customized by Django)?

Browser other questions tagged

You are not signed in. Login or sign up in order to post.