Elton Pereira de Lima
-----------------------------
Quem nada dúvida, nada descobre.
On Saturday 18 February 2017 22:27:46 Elton Pereira wrote:
> class ProdutoServicoManager(models.Manager):
> def get_queryset(self):
> expression = models.Sum(models.F('custounitario__valor') *
> models.F('custounitario__quantidade'))
> total_expr = models.ExpressionWrapper(expression,
> output_field=models.DecimalField())
> return
> super().get_queryset().annotate(custo_producao=total_expr)
>
> class ProdutoServico(Base):
What's the manager on Base?
> produto = models.BooleanField(default=True)
> descricao = models.TextField()
> objects = ProdutoServicoManager()
>
> class Meta:
> base_manager_name = 'objects'
Cause this doesn't actually do anything, beside being explicit.
--
Melvyn Sopacua
class Base(models.Model):
plano = models.ForeignKey(Plano)
class Meta:
abstract = True
On Monday 20 February 2017 17:09:40 eltonplima wrote:
> Base class is abstract.
>
> class Base(models.Model):
> plano = models.ForeignKey(Plano)
>
>
> class Meta:
> abstract = True
>
>
> base_manager_name
> <https://docs.djangoproject.com/en/1.10/ref/models/options/#base-manag
> er-name>
Ack, my brain kept reading "default_manager_name".
Still - without a ForeignKey this shouldn't break anything. It seems it warrents a new bug report, but I'm curious where things break. It looks like this model is used as an inline in the admin. Is that correct?
I cannot reproduce this with a simple test case:
models:
class CartEntryManager(models.Manager):
def get_queryset(self):
qs = super(CartEntryManager, self).get_queryset()
expression = models.F('quantity') * models.F('price')
wrapped = models.ExpressionWrapper(expression,
output_field=models.DecimalField(
max_digits=20, decimal_places=2))
return qs.annotate(amount=wrapped)
class Cart(models.Model):
created = models.DateTimeField(auto_now_add=True)
class CartEntry(models.Model):
item = models.CharField(max_length=32, primary_key=True)
quantity = models.PositiveSmallIntegerField()
price = models.DecimalField(max_digits=20, decimal_places=2)
cart = models.ForeignKey(Cart, on_delete=models.CASCADE,
related_name='items')
is_shipped = models.BooleanField(default=False)
objects = CartEntryManager()
class Meta:
base_manager_name = 'objects'
tests:
class CartTest(TestCase):
@classmethod
def setUpTestData(cls):
cart = models.Cart()
cart.save()
keyboard = models.CartEntry(
item='Komplete Kontrol S88',
quantity=2,
price='999.00',
cart=cart
)
mixer = models.CartEntry(
item='Traktor Kontrol S8',
quantity=1,
price='1199.00',
cart=cart
)
keyboard.save()
mixer.save()
cls.cart = cart
cls.keyboard = keyboard
cls.mixer = mixer
def test_entry_annotation(self):
self.assertEqual(self.keyboard.amount, 1998)
def test_base_manager(self):
from decimal import Decimal
total = Decimal('0.00')
for item in self.cart.items.all():
total += item.amount
total = total.quantize(Decimal('0.01'))
expect = Decimal('3197.00').quantize(Decimal('0.01'))
self.assertEqual(total, expect)
def test_base_manager_update(self):
self.cart.items.update(is_shipped=True)
shipped = self.cart.items.filter(is_shipped=True).count()
self.assertEqual(shipped, 2)
> On Saturday, February 18, 2017 at 9:20:03 PM UTC-3, Melvyn Sopacua wrote:
> > On Saturday 18 February 2017 22:27:46 Elton Pereira wrote:
> > > class ProdutoServicoManager(models.Manager):
> > >
> > > def get_queryset(self):
> > >
> > > expression = models.Sum(models.F('custounitario__valor') *
> > >
> > > models.F('custounitario__quantidade'))
> > >
> > > total_expr = models.ExpressionWrapper(expression,
> > >
> > > output_field=models.DecimalField())
> > >
> > > return
> > >
> > > super().get_queryset().annotate(custo_producao=total_expr)
> >
> > > class ProdutoServico(Base):
> > What's the manager on Base?
> >
> > > produto = models.BooleanField(default=True)
> > >
> > > descricao = models.TextField()
> > >
> > > objects = ProdutoServicoManager()
> > >
> > >
> > >
> > > class Meta:
> > >
> > > base_manager_name = 'objects'
> >
> > Cause this doesn't actually do anything, beside being explicit.
> >
> >
> >
> >
> > Melvyn Sopacua
--
Melvyn Sopacua
from django.db import models
class ProdutoServicoManager(models.Manager): def get_queryset(self): custo_unitario = models.F('custounitario__valor') quantidade = models.F('custounitario__quantidade') expression = models.Sum(custo_unitario * quantidade) custo_producao_expr = models.ExpressionWrapper(expression, output_field=models.DecimalField()) return super().get_queryset().annotate(custo_producao=custo_producao_expr)
class ProdutoServico(models.Model):
produto = models.BooleanField(default=True) descricao = models.TextField() objects = ProdutoServicoManager()
class Meta:
#################################################
# Comment the line below and the test pass.
################################################# base_manager_name = 'objects'
class CustoUnitario(models.Model): produto_servico = models.ForeignKey(ProdutoServico) item = models.CharField(max_length=128) quantidade = models.PositiveIntegerField() valor = models.DecimalField(max_digits=10, decimal_places=4, verbose_name='Valor unitário')
class Faturamento(models.Model): produto_servico = models.OneToOneField(ProdutoServico) quantidade = models.PositiveIntegerField() preco_unitario = models.DecimalField(max_digits=10, decimal_places=2)
# We need only a single simple test to demonstrate this issue.
from django.test import TestCasefrom django.db import utils
from model_mommy import mommy
from core import models
class FaturamentoTest(TestCase):
def test(self): faturamento = mommy.make(models.Faturamento) produto = faturamento.produto_servico try: produto.save() except utils.OperationalError: self.fail("Whats wrong?")
While the testcase is simple, it is not the simplest test :)
Two things come to mind:
In your original exception, it looks like ProdutoServico extends a model in sumario.models and both override the save method:
/home/eltonplima/ssd/repository/planonegocios/marketing/models.py in save
super().save(*args, **kwargs) ...
▶ Local vars
/home/eltonplima/ssd/repository/planonegocios/sumario/models.py in save
super().save(*args, **kwargs) ...
Is it possible your problem is in one of those two?