我在django中有以下功能,只需基于单个查找参数(unique_id)查找就可以正常工作。但是,我尝试使用多个查找参数(例如,具有unique_together约束的表,需要两个字段才能检索唯一结果)。
以前的工作功能是:
def create_or_update_if_diff(unique_id, defaults, model):
"""Helper function which is similar to update_or_create(), but will compare defaults to database entry
and only update when there is any difference"""
try:
instance = model.objects.get(unique_id=unique_id)
except model.DoesNotExist:
instance = model.objects.create(unique_id=unique_id, **defaults)
sys.stdout.write('New {} created: {}\n'.format(instance.__class__.__name__, instance.unique_id))
return instance
else:
for key, value in defaults.items():
attr = getattr(instance, key)
if attr != value:
# If any change detected update all for efficiency
model.objects.filter(unique_id=unique_id).update(**defaults)
instance.refresh_from_db()
sys.stdout.write('{}: {} updated \n'.format(instance.__class__.__name__, instance.unique_id))
return instance
return instance
用例如
prices = create_or_update_if_diff(unique_id=till_detail['Id'], defaults=defaults,
model=Price)
修改后的功能是:
def create_or_update_if_diff(model, defaults=None, **lookup):
"""Helper function which is similar to update_or_create(), but will compare defaults to database entry
and only update when there is any difference"""
defaults = defaults or {}
try:
instance = model.objects.get(**lookup)
except model.DoesNotExist:
instance = model.objects.create(**lookup, **defaults)
sys.stdout.write('New {} created: {}\n'.format(instance.__class__.__name__, instance.unique_id))
return instance
else:
for key, value in defaults.items():
attr = getattr(instance, key)
if attr != value:
# If any change detected update all for efficiency
model.objects.filter(**lookup).update(**defaults)
instance.refresh_from_db()
sys.stdout.write('{}: {} updated \n'.format(instance.__class__.__name__, instance.unique_id))
return instance
return instance
我试图用例如
lookup = {'name': default_product_string, 'supplier': supplier}
default_product_instance = create_or_update_if_diff(lookup=lookup, defaults={'payment_method': payment_method_instance},
model=Product)
但是我得到了以下错误,大概是因为我已经非正式地构建了这个函数:
django.core.exceptions.FieldError: Cannot resolve keyword 'lookup' into field.
答案 0 :(得分:1)
发送kwargs
时出错了,这就是它的工作方式......
让我们创建一个样本lookup
dict ..
>>> lookup = {'a': 1, 'b': 2}
模拟create_or_update_if_diff
方法......
>>> def create_or_update_if_diff(model, defaults=None, **lookup):
... print lookup
如果您在调用方法时分配lookup=lookup
....这意味着您正在创建一个名为key word argument
的{{1}},理想情况下您只发送一个关键字参数
lookup
由于您的模型没有
>>> create_or_update_if_diff('model', lookup=lookup) {'lookup': {'a': 1, 'b': 2}}
字段,因此您将获得lookup
例外。
如果您传递FieldError
dict,如下所示...您正在向方法发送两个关键字参数lookup
..
a and b
所以,这里的逻辑是>>> create_or_update_if_diff('model', **lookup)
{'a': 1, 'b': 2}
dict lookup
有两个键{'a':1, 'b':2}
将被视为如下所示。
a and b
希望这可以帮助您了解>>> create_or_update_if_diff('model', a=1, b=2)
{'a': 1, 'b': 2}
的工作原理......
答案 1 :(得分:0)
如果您将lookup=lookup
作为参数,则会在函数中获得{'lookup': {<your original dict>}}
。我认为你应该在你的函数中create_or_update_if_diff
:
lookup_params = lookup['lookup']
instance = model.objects.get(lookup_params)
答案 2 :(得分:0)
您没有正确传递lookup
,以下是它的假设:
lookup = {'name': default_product_string, 'supplier': supplier}
defaults = {'payment_method': payment_method_instance}
create_or_update_if_diff(defaults=defaults, model=Product, **lookup)