Python 需要在Django中保存估算模型
我在Django中有以下models.py和admin.py文件。我想做两件事Python 需要在Django中保存估算模型,python,django,Python,Django,我在Django中有以下models.py和admin.py文件。我想做两件事 合并Environment和ItemObject的specs字段,并将其存储到Environment的specs中,这是我之所以能够做到的,因为我能够找到放置逻辑的位置。(class AddEnvironmentDetailsInlineForm(forms.ModelForm)) 我需要做同样的估计。我需要获取Environment.specs和Estimate.specs,将两者合并并保存在Estimate.sp
class AddEnvironmentDetailsInlineForm(forms.ModelForm)
)class Estimate(CommonModel):
...
class Environment(CommonModel):
estimate = models.ForeignKey(Estimate,related_name='environments')
logic = PythonCodeField(blank=True, null=True)
...
class Item(CommonModel):
...
class ItemTemplate(Item):
pass
class ItemObject(Item):
pass
class EnvironmentDetail(models.Model):
environment = models.ForeignKey(Environment)
item_name = models.CharField(max_length=200,blank=True)
qty = models.FloatField('Qty')
...
管理员
class CommonAdmin(admin.ModelAdmin):
...
class EnvironmentInlineAdmin (admin.TabularInline):
model = Environment
...
formfield_overrides = {
JSONField:{ 'widget':JSONEditor },
}
...
def save_model(self, request, obj, *kwargs):
if request.user.is_superuser or request.user==obj.author:
obj.author.id=request.user.id
super(EnvironmentInlineAdmin,self).save_model(request, obj, *kwargs)
else:
raise ValidationError("author must be you")
class EstimateAdmin (CommonAdmin):
inlines = [ EnvironmentInlineAdmin ]
list_display = ('title', 'gp_code', 'otc_price','annual_price')
admin.site.register(Estimate,EstimateAdmin)
class EnvironmentDetailsInlineForm(forms.ModelForm):
class Meta:
model = EnvironmentDetail
fields = ['item_name','qty']
show_change_link = True
class AddEnvironmentDetailsInlineForm(forms.ModelForm):
class Meta:
model = EnvironmentDetail
fields = ['item_name','item', 'qty']
item = forms.ModelChoiceField(queryset=ItemTemplate.objects.all())
def clean(self):
instance = self.cleaned_data['item']
item_specs = self.cleaned_data['item'].specs
environment_specs = self.cleaned_data['environment'].specs
environment_specs.update(item_specs)
fields = [f.name for f in Item._meta.fields]
values = dict( [(x, getattr(instance, x)) for x in fields] )
new_instance = ItemObject(**values)
new_instance.save() #save new one
#instance.delete() # remove the old one
self.cleaned_data['item'] = new_instance
return self.cleaned_data # Return self.cleaned_data at the end of clean()
def save_model(self, request, obj, *kwargs):
if request.user.is_superuser or request.user==obj.author:
super(AddEnvironmentDetailsInlineForm,self).save_model(request, obj, *kwargs)
else:
raise ValidationError("author must be you")
class EnvironmentDetailsInlineAdmin (admin.TabularInline):
model = EnvironmentDetail
...
form = EnvironmentDetailsInlineForm
formfield_overrides = {
JSONField:{ 'widget':JSONEditor },
}
def change_link(self, obj):
return mark_safe('<a href="%s">Edit Item</a>' % \
reverse('admin:estimate_itemobject_change',
args=(obj.item.id,)))
def item_type(self, obj):
return obj.item.item_type
...
class AddEnvironmentDetailsInlineAdmin (admin.TabularInline):
model = EnvironmentDetail
fields = ('item_name','item', 'qty', )
form = AddEnvironmentDetailsInlineForm
def has_change_permission(self, request, obj=None):
return False
def item(self,obj):
return ItemTemplate
class EnvironmentAdmin (CommonAdmin):
model=Environment
save_as = True
inlines = [ EnvironmentDetailsInlineAdmin,AddEnvironmentDetailsInlineAdmin]
...
def get_model_perms(self, request):
"""
Return empty perms dict thus hiding the model from admin index.
"""
return {}
admin.site.register(Environment,EnvironmentAdmin)
与您的问题相比,您的代码非常大。我减少了一点代码。添加了它们,这样如果有人问,它就会在那里。正如我从你的问题中了解到的,你想在一个下拉列表中从两个模型中获取数据吗?不。你看,当估计值注册时,它也有环境。环境将具有字段(例如,规范,它是一个字典)。Estimate还有specs字段,它也是一个字典。我想知道把逻辑放在哪里,这样我就可以把两者合并。因此,当我保存模型时,估计值的规格会更新。我认为您需要信号来解决您的问题,它有两种风格:pre和post,顾名思义,它们在保存数据之前和保存数据之后工作。您在最后阶段需要的数据可以通过查询进行合并,但场景可以通过django中的信号进行处理
@receiver(post_save, sender=Estimate)
def update_specs_estimate(sender, instance, **kwargs):
print("instance", instance.specs)
return instance.specs
@receiver(post_save, sender=Environment)
def take_specs_environment(sender, instance, **kwargs):
print("instance", instance.specs)
return instance.specs
def dict_merge(update_specs_estimate, take_specs_environment):
return (update_specs_estimate.update(take_specs_environment))