我正在使用django v1.10.2
我正在尝试创建动态报告,我将字段和条件以及主要的ORM模型信息存储到数据库中。
我生成动态报告的代码是
main_model_name
所以main_model
可以是任何东西
这项工作很有效,但有时choicefield
的关联模型有main_model
。
因此,其中一个报告Pallet
为Pallet
PalletMovement
有很多serial_number
我的显示列为:created_at
,pallet_movement__location
,Pallet
前两列是属于PalletMovement
模型的字段。
最后一个来自PalletMovement
class PalletMovement(models.Model):
pallet = models.ForeignKey(Pallet, related_name='pallet_movements',
verbose_name=_('Pallet'))
WAREHOUSE_CHOICES = (
('AB', 'AB-Delaware'),
('CD', 'CD-Delaware'),
)
location = models.CharField(choices=WAREHOUSE_CHOICES,
max_length=2,
default='AB',
verbose_name=_('Warehouse Location'))
模型看起来像这样:
choicefield
由于查询集会返回原始值,如何使用PalletMovement
模型中的pallet_movement__location
来确保AB-Delaware
显示CD-Delaware
}或main_model
?
请记住,// assumes this.viewer contains your viewer, your code might be different ...
// make sure viewer has been created
if (this.viewer) {
// I added this to handle some specific cases
if(this.viewer.impl.selector) {
this.viewer.tearDown()
this.viewer.finish()
this.viewer = null
}
}
可以是任何内容,具体取决于我在数据库中存储的内容。
据推测,我可以在数据库中存储更多信息,以帮助我更好地过滤和呈现数据。
答案 0 :(得分:4)
values()
方法返回表示字段名称和相应值的键值对字典。
例如:
型号:
class MyModel(models.Model):
name = models.CharField()
surname = models.CharField()
age = models.IntegerField()
...
查询:
result = MyModel.objects.filter(surname='moutafis').values('name', 'surname')
结果:
< Queryset [{'name': 'moutafis', 'surname': 'john'}] >
您现在可以像处理普通词典一样操纵此结果:
if main_model_name is 'PalletMovement':
# Make life easier
choices = dict(PalletMovement.WAREHOUSE_CHOICES)
for item in result:
item.update({
pallet_movement__location: verbal_choice.get(
pallet_movement__location, pallet_movement__location)
})
您甚至可以将其转换为更好的可重用性功能:
def verbalize_choices(choices_dict, queryset, search_key):
result = queryset
for item in result:
item.update({ search_key: choices_dict.get(search_key, search_key) })
return result
verbal_result = verbalize_choices(
dict(PalletMovement.WAREHOUSE_CHOICES),
result,
'pallet_movement__location'
)
我建议使用update()
和get()
方法,因为它们可以避免潜在的错误,例如:
search_key
中不存在choice_dict
,然后get()
会返回search_key
update()
会尝试更新给定的键值对(如果存在),否则会将其添加到字典中。如果上述内容的使用位于数据的模板表示中,则可以改为创建custom template filter:
@register.filter(name='verbalize_choice')
def choice_to_verbal(choice):
return dict(PalletMovement.WAREHOUSE_CHOICES)[choice]
答案 1 :(得分:1)
您可以使用{{ obj.get_location_display }}
在你的模板中:
{{ obj.pallet_movement.get_location_display }}
或
values()
[编辑:]正如评论中所指出的,这在调用{{1}}
时无效答案 2 :(得分:1)
创建模板标签的替代方法是:
{{form.choicefield.1}}
这显示了外键字段的初始数据的值,而不是id。
答案 3 :(得分:1)
任何main_model_name
的通用解决方案都是由Django Model _meta API内省: class_object._meta.get_field(field_name).choices
那就是:
choice_dicts = {}
for field_name in display_columns:
choice_dicts[field_name] = {
k: v for k, v in class_object._meta.get_field(field_name).choices
}
out = []
for row in results:
out.append({name: choice_dicts[name].get(value, value)
for name, value in row.items()
})
其余的是一个琐碎的例子,大多是从问题
复制的代码>>> pallet = app.models.Pallet.objects.create()
>>> palletm = app.models.PalletMovement.objects.create(pallet=pallet, location='AB')
>>>
>>> main_model_name = 'PalletMovement'
>>> conditions_dict = {}
>>> display_columns = ['pallet_id', 'location']
>>> sort_columns = []
>>>
>>> class_object = class_for_name("app.models", main_model_name)
>>> results = (class_object.objects.filter(**conditions_dict)
... .values(*display_columns)
... .order_by(*sort_columns)
... )[:50]
>>>
>>> # *** INSERT HERE ALL CODE THAT WAS ABOVE ***
>>>
>>> print(out)
[{'location': 'AB-Delaware', 'pallet_id': 1}]
它与&#39; pallet_id&#39;同等作用。或者使用托盘&#39;在display_columns
。即使那样&#34; _meta&#34;从下划线开始,它是一个记录的API。