我在Django中有下面的models.py和admin.py文件。我想做两件事
class AddEnvironmentDetailsInlineForm(forms.ModelForm)
)合并就像ItemObject - >环境 - >估计
挑战在于我无法弄清楚将这种逻辑放在Estimate和Environment的哪个位置。我是否需要为Estimate创建ModelForm才能实现合并?我不清楚文件的逻辑(我还在学习Django中的概念)。如果有人能让我明白,那就太好了。
models.py
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')
...
admin.py
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)
我在下面尝试但是现在这个(dict_merge)需要保存到Estimate
@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))