确实很奇怪的问题-当我查询模型实例时,数据又被分配给错误的属性。
模型:
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
答案 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__来定制模型 方法。但是,如果这样做,请注意不要更改呼叫 签名。 。