Django查询将数据库列分配给错误的模型实例属性

时间:2019-07-19 07:27:24

标签: django django-models django-queryset

确实很奇怪的问题-当我查询模型实例时,数据又被分配给错误的属性。

模型:

class SaleLineItem(models.Model):
    sale = models.ForeignKey(Sale, on_delete=models.CASCADE, related_name="sale_line_items")
    stock_unit = models.ForeignKey(StockUnit, on_delete=models.CASCADE, related_name="sale_line_items")

    currency = models.CharField(max_length=3)
    price_original = models.FloatField()
    price_paid = models.FloatField()

    tax_amount = models.FloatField(null=True, blank=True)

    num_sold = models.IntegerField()

    sale_line_item_id = models.CharField(max_length=30, null=True, blank=True)

    status = models.CharField(max_length=20, choices=SALE_STATUS_CHOICES, null=True, blank=True)

数据库行:

  id   | currency | price_original | price_paid | tax_amount | num_sold | sale_line_item_id |  status   | sale_id | stock_unit_id 
-------+----------+----------------+------------+------------+----------+-------------------+-----------+---------+---------------
 15726 | THB      |            130 |        130 |            |        1 |                   | delivered |   16219 |             2

查询:

sli = SaleLineItem.objects.get(pk=15726)
print(sli.pk)
-------------------------
16219

print(sli.stock_unit_id)
-------------------------
THB

print(sli.currency)
-------------------------
130.0

数据被填充到对象上,但是所有内容都被“移动”了一列。

但是如果我这样查询:

SaleLineItem.objects.filter(pk=15726).values()
-------------------------
<QuerySet [{'id': 15726, 'sale_id': 16219, 'stock_unit_id': 2, 'currency': 'THB', 'price_original': 130.0, 'price_paid': 130.0, 'tax_amount': None, 'num_sold': 1, 'sale_line_item_id': None, 'status': 'delivered'}]>

。 。 。结果是正确的。

我以为我可能有未迁移的模型,但是我同时进行了makemigrations和迁移,但都没有效果。

使用较低级别的QuerySet方法时,结果相同:

qs = SaleLineItem.objects.all()
clone = qs._chain()
clone.query.add_q(Q(pk=15726))
print(clone)
------------------------------
<QuerySet [<SaleLineItem: SaleLineItem object (16219)>]>

请注意,模型__str __上的pk不正确。

有什么想法吗?

运行:

Python 3.7.3 Django 2.2.1 Postgres 10

1 个答案:

答案 0 :(得分:0)

结果是因为我用一个额外的(非字段)参数覆盖了__init __。

    @classmethod
    def from_db(cls, db, field_names, values):
        if len(values) != len(cls._meta.concrete_fields):
            values_iter = iter(values)
            values = [
                next(values_iter) if f.attname in field_names else DEFERRED
                for f in cls._meta.concrete_fields
            ]
        new = cls(*values)
        new._state.adding = False
        new._state.db = db
        return new

使用* values将数据库值填充到模型中,并且模型期望字段以特定顺序排列。因此,您不能在__init__中添加额外的参数,否则顺序会混乱。

编辑:

尚未在文档(https://docs.djangoproject.com/en/2.1/ref/models/instances/)中阅读此部分:

  

您可能会通过覆盖__init__来定制模型   方法。但是,如果这样做,请注意不要更改呼叫   签名。 。