0
Good afternoon Galera,
My situation is as follows. I have a nested class structure for a solution and I’m stuck in the following situation: I have these class structure:
class Atividade_estruturas_complementares(models.Model):
atividades_complementares = models.OneToOneField(Atividade, on_delete=models.PROTECT,
related_name='atividades_complementares')
class Meta:
verbose_name_plural = 'Estruturas Complementares'
verbose_name = 'Estruturas Complementares'
def __str__(self):
return self.atividades_complementares.nome
class Estruturas_complementares(models.Model):
passivo_id = models.ForeignKey(Passivo,
related_name='complementares',
on_delete=models.CASCADE)
atividade_complementar = models.ForeignKey(Atividade_estruturas_complementares, on_delete=models.PROTECT,
related_name='atividade_estruturas_complementares')
comprimento = models.DecimalField(
'Comprimento', max_digits=10, decimal_places=2, blank=True, null=True, default=None)
largura_altura = models.DecimalField(
'Largura / Altura', max_digits=6, decimal_places=2, blank=True, null=True)
profundidade = models.DecimalField(
'Profundidade', max_digits=10, decimal_places=2, blank=True, null=True, default=None)
valor = models.FloatField(default=0.0)
The Structures_complementary class is registered in admin as inline and assigned to another model called Passive. When saving the liability I would like to update the value field of the Structures_complementary class with a function that makes a specific calculation, I already have the function but do not know how to relate so that the moment I save the passive object I call the function that includes the value in the structures_complementary object. I thought about the possibility of calling a function in default, but did not succeed.
I would like some help to improve this implementation as I am still new to Django and python. In case you need more information I am available.
py.models All classes are in the same models.py, it’s a huge file, but I think the most important one in this case would be the passive class, which is the core of the system, and is represented below. Edit* "ALL CLASSES BELOW"
from django.contrib.gis.db import models
from djgeojson.fields import PointField
from django.contrib.gis.geos import Point
from django.contrib.gis.geos import GEOSGeometry
from django.contrib.gis.gdal import SpatialReference, CoordTransform
from bdg import models as bdg_models
from django.contrib.gis.measure import D
import django_tables2 as tables
from sorl.thumbnail import ImageField
from rest_framework import serializers
from smart_selects.db_fields import ChainedManyToManyField
from django.contrib import messages
from django.shortcuts import render
from .thumbs import ImageWithThumbsField
from sorl_thumbnail_serializer.fields import HyperlinkedSorlImageField
from drf_dynamic_fields import DynamicFieldsMixin
from django.core.validators import FileExtensionValidator
import zipfile
from sicro.models import Sicro
class Unidade(models.Model):
nome = models.CharField('Nome', max_length=20)
sigla = models.CharField('Sigla', max_length=5)
def __str__(self):
return str(self.sigla)
class Atividade(models.Model):
codigoSICRO = models.OneToOneField(Sicro, on_delete=models.CASCADE, unique=True, primary_key=True)
nome = models.CharField('Nome', max_length=200, unique=True)
descricao = models.TextField('Descrição', max_length=300, blank=True)
unidadeMedida = models.ForeignKey(Unidade, on_delete=models.DO_NOTHING)
def __str__(self):
return self.nome
class Reparo(models.Model):
nome = models.CharField('Nome', max_length=100, blank=True)
descricao = models.TextField('Descrição', max_length=300, blank=True)
atividades = models.ManyToManyField(Atividade)
def __str__(self):
return self.nome
class Causa(models.Model):
# feicao = models.ManyToManyField(Feicao)
nome = models.CharField(max_length=250, null=True, blank=True)
def __str__(self):
return self.nome
class Meta:
verbose_name_plural = "Causas"
class Consequencia(models.Model):
nome = models.CharField(max_length=250, null=True, blank=True)
valoracao = models.FloatField('Valoração', default=0.0)
def __str__(self):
return self.nome
class Meta:
verbose_name_plural = "Consequências"
verbose_name = "Consequência"
class Feicao(models.Model):
# Opcoes Tipo
erosao_uniforme = 'Erosão Uniforme'
erosao_concentrada = 'Erosão Concentrada'
escorregamento_rotacional = 'Escorregamento Rotacional'
escorregamento_planar = 'Escorregamento Planar'
queda_blocos_tombamento = 'Queda de blocos/tombamento'
corrida = 'Corrida'
rastejo = 'Rastejo'
adensamento = 'Adensamento'
tipos_opcoes = (
(erosao_uniforme, "Erosão Uniforme"),
(erosao_concentrada, "Erosão Concentrada"),
(escorregamento_rotacional, "Escorregamento Rotacional"),
(escorregamento_planar, "Escorregamento Planar"),
(queda_blocos_tombamento, "Queda de blocos / tombamento"),
(corrida, "Corrida"),
(rastejo, "Rastejo"),
(adensamento, "Adensamento")
)
nome = models.CharField(
max_length=50, choices=tipos_opcoes, blank=True, null=True)
causas = models.ManyToManyField(Causa)
consequencias = models.ManyToManyField(Consequencia)
def __str__(self):
return self.nome
class Meta:
verbose_name_plural = "Feições"
def calculoReparo(dimensao_comprimento, largura_faixa_dominio_total, dimensao_profundidade, metodos_reparo,
siglaEstado):
comprimento = dimensao_comprimento
altura_largura = largura_faixa_dominio_total
profundidade = dimensao_profundidade
estado = siglaEstado.lower()
soma = 0.0
for atividade in metodos_reparo.atividades.all():
if atividade.unidadeMedida.sigla == 'm':
valores = Sicro.objects.all().filter(codigo=str(atividade.codigoSICRO)).values(estado)
valor = list(valores[0].values())
soma += valor[0] * float(comprimento)
elif atividade.unidadeMedida.sigla == 'tkm':
valores = Sicro.objects.all().filter(codigo=str(atividade.codigoSICRO)).values(estado)
valor = list(valores[0].values())
pass
elif atividade.unidadeMedida.sigla == 'un':
valores = Sicro.objects.all().filter(codigo=str(atividade.codigoSICRO)).values(estado)
valor = list(valores[0].values())
soma += valor[0]
elif atividade.unidadeMedida.sigla == 'm²':
valores = Sicro.objects.all().filter(codigo=str(atividade.codigoSICRO)).values(estado)
valor = list(valores[0].values())
soma += valor[0] * float((comprimento * altura_largura))
elif atividade.unidadeMedida.sigla == 'm³':
valores = Sicro.objects.all().filter(codigo=str(atividade.codigoSICRO)).values(estado)
valor = list(valores[0].values())
soma += valor[0] * float((comprimento * altura_largura * profundidade))
return soma
valor_protecao_superficial = 0.0
valor_estruturas_complementares = 0.0
def calculoComplementares(atividade, comprimento, largura_altura, profundidade, passivo):
estado = passivo.siglaEstado.lower()
soma = 0.0
if atividade.unidadeMedida.sigla == 'm':
valores = Sicro.objects.all().filter(codigo=str(atividade.codigoSICRO)).values(estado)
valor = list(valores[0].values())
soma += valor[0] * float(comprimento)
elif atividade.unidadeMedida.sigla == 'tkm':
valores = Sicro.objects.all().filter(codigo=str(atividade.codigoSICRO)).values(estado)
valor = list(valores[0].values())
pass
elif atividade.unidadeMedida.sigla == 'un':
valores = Sicro.objects.all().filter(codigo=str(atividade.codigoSICRO)).values(estado)
valor = list(valores[0].values())
soma += valor[0]
elif atividade.unidadeMedida.sigla == 'm²':
valores = Sicro.objects.all().filter(codigo=str(atividade.codigoSICRO)).values(estado)
valor = list(valores[0].values())
soma += valor[0] * float((comprimento * largura_altura))
elif atividade.unidadeMedida.sigla == 'm³':
valores = Sicro.objects.all().filter(codigo=str(atividade.codigoSICRO)).values(estado)
valor = list(valores[0].values())
soma += valor[0] * float((comprimento * largura_altura * profundidade))
elif atividade.unidadeMedida.sigla == 't':
valores = Sicro.objects.all().filter(codigo=str(atividade.codigoSICRO)).values(estado)
valor = list(valores[0].values())
soma += valor[0] * float((comprimento))
return soma
def calculoSuperficial(atividade, comprimento, largura_altura, profundidade, passivo):
estado = passivo.siglaEstado.lower()
soma = 0.0
if atividade.unidadeMedida.sigla == 'm':
valores = Sicro.objects.all().filter(codigo=str(atividade.codigoSICRO)).values(estado)
valor = list(valores[0].values())
soma += valor[0] * float(comprimento)
elif atividade.unidadeMedida.sigla == 'un':
valores = Sicro.objects.all().filter(codigo=str(atividade.codigoSICRO)).values(estado)
valor = list(valores[0].values())
soma += valor[0]
elif atividade.unidadeMedida.sigla == 'm²':
valores = Sicro.objects.all().filter(codigo=str(atividade.codigoSICRO)).values(estado)
valor = list(valores[0].values())
soma += valor[0] * float((comprimento * largura_altura))
elif atividade.unidadeMedida.sigla == 'm³':
valores = Sicro.objects.all().filter(codigo=str(atividade.codigoSICRO)).values(estado)
valor = list(valores[0].values())
soma += valor[0] * float((comprimento * largura_altura * profundidade))
return soma
class Abrangencia(models.Model):
atributo = models.CharField('Atributo', blank=True,
null=True, max_length=20)
valoracao = models.FloatField('Valoração', default=1.0)
descricao = models.TextField()
class Meta:
verbose_name_plural = 'Abrangências'
verbose_name = 'Abrangência'
def __str__(self):
return self.atributo
class Magnitude(models.Model):
atributo = models.CharField('Atributo', blank=True,
null=True, max_length=20)
valoracao = models.FloatField('Valoração', default=1.0)
erosao = models.TextField('Erosão', )
movimento_massa = models.TextField('Movimentos de massa', )
adensamento = models.TextField('Adensamento', )
class Meta:
verbose_name_plural = 'Magnitudes'
verbose_name = 'Magnitude'
def __str__(self):
return self.atributo
class Interferencia(models.Model):
descricao = models.CharField('Descrição', blank=True,
null=True, max_length=100)
valoracao = models.FloatField('Valoração', default=1.0)
class Meta:
verbose_name_plural = 'Interferências'
verbose_name = 'Interferência'
def __str__(self):
return self.descricao
def calculaGrandeza(abrangencia, magnitude):
grandeza = (abrangencia.valoracao + magnitude.valoracao) / 2
return grandeza
def calculaRisco(risco_ao_usuario, provaveis_consequencias):
risco = 0.0
consequencias = provaveis_consequencias.all()
for consequencia in consequencias:
risco += consequencia.valoracao
risco = risco * risco_ao_usuario
return risco
def calculaIndicePrioridade(self):
g = calculaGrandeza(self.abrangencia, self.magnitude)
# teste = self.provaveis_consequencias.all()
r = calculaRisco(self.risco_ao_usuario, self.provaveis_consequencias)
it = self.interferencia.valoracao
ip = (0.55 * r) + (0.1 * g) + (0.1 * it)
return ip
class Passivo(models.Model):
# Opcoes relevo
plano = 'PL'
ondulado = 'ON'
montanhoso = 'MO'
relevo_opcoes = (
(plano, 'Plano'),
(ondulado, 'Ondulado'),
(montanhoso, 'Montanhoso')
)
# Opcoes terceira_faixa_localizacao
lado_direito = 'LD'
lado_esquerdo = 'LE'
inexistente = 'IN'
ambos = 'AM'
terceira_faixa_localizacao_opcoes = (
(lado_direito, 'Lado Direito'),
(lado_esquerdo, 'Lado Esquerdo'),
(inexistente, 'Inexistente')
)
# opcoes pavimento
pavimento_asfautico = 'PA'
pavimento_concreto = 'PC'
nao_pavimentado = 'NP'
outro_pavimento = 'OP'
pista_rolamento_pavimento_opcoes = (
(pavimento_asfautico, 'Pavimento Asfaltico'),
(pavimento_concreto, 'Pavimento Concreto'),
(nao_pavimentado, 'Nao Pavimentado'),
(outro_pavimento, 'Outro Pavimento')
)
# opcoes lado
direito = 'D'
esquerdo = 'E'
indefinido = 'I'
ambos = 'A'
lado_opcoes = (
(direito, 'Direito'),
(esquerdo, 'Esquerdo'),
(indefinido, 'Indefinido'),
(ambos, 'Lado Direito e Esquerdo')
)
# Opcoes Perigo e sua valoração
sem_perigo = 0.0
perigo_potencial = 0.5
perigo_iminente = 1.0
perigo_instalado = 1.5
nivel_gravidade_escolhas = (
(sem_perigo, 'Sem Perigo'),
(perigo_potencial, 'Perigo Potencial'),
(perigo_iminente, 'Perigo Iminente'),
(perigo_instalado, 'Perigo Instalado')
)
# MODELO
data_inspecao = models.DateField('Data de inspeção', auto_now=False)
# LOCALIZAÇÃO
latitude = models.DecimalField(
'Latitude', max_digits=14, decimal_places=10, blank=False, null=True)
longitude = models.DecimalField(
'Longitude', max_digits=14, decimal_places=10, blank=False, null=True)
km_ponto = models.DecimalField(
'Km', blank=True, null=True, max_digits=7, decimal_places=2)
lado = models.CharField('Lado de Ocorrência', blank=True,
null=True, max_length=1, choices=lado_opcoes)
distancia_ao_eixo = models.CharField(
'Distância do Passivo ao Eixo', max_length=50, blank=True, null=True)
area_ocorrencia_faixa_dominio = models.NullBooleanField(
blank=True, null=True, default=False)
area_ocorrencia_area_adjacente = models.NullBooleanField(
blank=True, null=True, default=False)
# CARACTERIZAÇÃO DO SEGMENTO RODOVIÁRIO
largura_faixa_dominio_esquerda = models.DecimalField(
max_digits=6, decimal_places=2, blank=True, null=True)
largura_faixa_dominio_direita = models.DecimalField(
max_digits=6, decimal_places=2, blank=True, null=True)
pista_rolamento_numero = models.IntegerField(
'nº de pistas de rolamento', blank=True, null=True)
pista_rolamento_pavimento = models.CharField(max_length=50,
choices=pista_rolamento_pavimento_opcoes,
default=pavimento_asfautico)
acostamento_presenca = models.NullBooleanField(
'Acostamento', default=False)
terceira_faixa_localizacao = models.CharField('Terceira Faixa / Localização', max_length=50,
choices=terceira_faixa_localizacao_opcoes,
default=inexistente)
relevo = models.CharField(max_length=50,
choices=relevo_opcoes,
default=plano)
# CARACTERIZAÇÃO DO PASSIVO
feicao = models.ForeignKey(Feicao, on_delete=models.DO_NOTHING)
risco_ao_usuario = models.FloatField(choices=nivel_gravidade_escolhas, default=None, blank=True, null=True)
risco_ao_patrimonio = models.FloatField(choices=nivel_gravidade_escolhas, default=None, blank=True, null=True)
risco_ao_ambiente = models.FloatField(choices=nivel_gravidade_escolhas, default=None, blank=True, null=True)
possiveis_causas = ChainedManyToManyField(
Causa,
horizontal=True,
verbose_name='Possiveis Causas',
chained_field="feicao",
chained_model_field="feicao",
)
provaveis_consequencias = ChainedManyToManyField(
Consequencia,
horizontal=True,
verbose_name='Provaveis Consequências',
chained_field="feicao",
chained_model_field="feicao",
)
abrangencia = models.ForeignKey(Abrangencia, on_delete=models.CASCADE, null=True)
magnitude = models.ForeignKey(Magnitude, on_delete=models.CASCADE, null=True)
interferencia = models.ForeignKey(Interferencia, on_delete=models.CASCADE, null=True)
localizacao = models.PointField(blank=True, null=True)
modelo_3d = models.FileField(upload_to='models/', blank=True, null=True,
validators=[FileExtensionValidator(allowed_extensions=['zip'])])
modelo_3d_path = models.CharField(
'Endereço do arquivo 3d (cloud.js)', max_length=128, blank=True, null=True)
croqui = models.ImageField('Croqui', blank=True, null=True)
observacoes = models.TextField('Observações', blank=True, null=True)
segmento_rodoviario = models.ForeignKey(
bdg_models.Rodovia, on_delete=models.CASCADE, blank=True, null=True, unique=False,
verbose_name='Segmento Rodoviário')
estado = models.CharField('Estado', blank=True, null=True, max_length=50)
siglaEstado = models.CharField('Sigla', blank=True, null=True, max_length=2)
municipio = models.CharField(
'Município', blank=True, null=True, max_length=50)
# MÉTODOS DE REPARO
metodos_reparo = models.ForeignKey(Reparo, on_delete=models.CASCADE, null=True)
dimensao_comprimento = models.DecimalField(
'Comprimento', max_digits=10, decimal_places=2, blank=True, null=True, default=None)
largura_faixa_dominio_total = models.DecimalField(
'Largura / Altura', max_digits=6, decimal_places=2, blank=True, null=True)
dimensao_profundidade = models.DecimalField(
'Profundidade', max_digits=10, decimal_places=2, blank=True, null=True, default=None)
valor_total_reparo = models.FloatField('valor reparo', default=0.0)
indice_prioridade = models.FloatField('Indice de Prioridade', default=0.0)
def save(self, *args, **kwargs):
if ((self.latitude != None) & (self.longitude != None)):
coordinate = 'POINT(' + str(self.longitude) + \
' ' + str(self.latitude) + ')'
try:
RODOVIA_FROM_LOCALIZACAO_ID = bdg_models.Rodovia.objects.filter(
geom__distance_lt=(GEOSGeometry(coordinate), D(m=5000)))[0]
self.segmento_rodoviario = RODOVIA_FROM_LOCALIZACAO_ID
except RuntimeError:
print('Something wrong with input points')
raise
try:
ESTADO_FROM_LOCALIZACAO_ID = bdg_models.Estado.objects.filter(
geom__intersects=(GEOSGeometry(coordinate)))
self.estado = ESTADO_FROM_LOCALIZACAO_ID[0].nome
self.siglaEstado = ESTADO_FROM_LOCALIZACAO_ID[0].sigla
self.valor_total_reparo = calculoReparo(self.dimensao_comprimento, self.largura_faixa_dominio_total,
self.dimensao_profundidade, self.metodos_reparo,
self.siglaEstado)
self.indice_prioridade = calculaIndicePrioridade(self)
protecao_superficial = Protecao_superficial.objects.all()
protecao_superficial
for atividade in protecao_superficial:
print(atividade)
except RuntimeError:
print('Something wrong with input points')
raise
try:
MUNICIPIO_FROM_LOCALIZACAO_ID = bdg_models.Municipio.objects.filter(
geom__intersects=(GEOSGeometry(coordinate)))
self.municipio = MUNICIPIO_FROM_LOCALIZACAO_ID[0].nome
except RuntimeError:
print('Something wrong with input points')
raise
self.localizacao = GEOSGeometry(coordinate)
if self.modelo_3d:
try:
targetdir = 'static/models'
targetname = '/' + str(self.id)
self.modelo_3d_path = '/models' + targetname + '/cloud.js'
with zipfile.ZipFile(self.modelo_3d, "r") as zip_ref:
zip_ref.extractall(targetdir + targetname)
except RuntimeError:
print('Something wrong with the unziping')
raise
else:
pass
else:
print('Preencher coordenadas')
super(Passivo, self).save(*args, **kwargs)
class Meta:
verbose_name_plural = "Passivos"
# def all_images(self):
# # code to determine which image to show. The First in this case.
# return self.fotos
def __str__(self):
return str(self.id)
# PROTEÇÃO SUPERFICIAL
class Atividade_protecao_superficial(models.Model):
atividade_superficial = models.ForeignKey(Atividade, on_delete=models.PROTECT,
related_name='atividade_superficial', primary_key=True)
class Meta:
verbose_name_plural = 'Atividades Superficiais'
verbose_name = 'Atividade Superficial'
def __str__(self):
return self.atividade_superficial.nome
class Protecao_superficial(models.Model):
passivo_id = models.ForeignKey(Passivo,
related_name='superficial',
on_delete=models.CASCADE)
atividade_superficial = models.ForeignKey(Atividade_protecao_superficial, on_delete=models.PROTECT,
related_name='atividade_protecao_superficial')
comprimento = models.DecimalField(
'Comprimento', max_digits=10, decimal_places=2, blank=True, null=True, default=None)
largura_altura = models.DecimalField(
'Largura / Altura', max_digits=6, decimal_places=2, blank=True, null=True)
profundidade = models.DecimalField(
'Profundidade', max_digits=10, decimal_places=2, blank=True, null=True, default=None)
valor = models.FloatField(default=0.0)
class Meta:
verbose_name_plural = 'Proteções Superficiais'
verbose_name = 'Proteção Superficial'
unique_together = (('passivo_id', 'atividade_superficial'),)
def __str__(self):
return ''
# ESTRUTURAS COMPLEMENTARES
class Atividade_estruturas_complementares(models.Model):
atividade_complementar = models.ForeignKey(Atividade, on_delete=models.PROTECT,
related_name='atividade_complementar', primary_key=True)
class Meta:
verbose_name_plural = 'Atividades Complementares'
verbose_name = 'Atividade Complementar'
def __str__(self):
return self.atividade_complementar.nome
class Estruturas_complementares(models.Model):
passivo_id = models.ForeignKey(Passivo,
related_name='complementares',
on_delete=models.CASCADE)
atividade_complementar = models.ForeignKey(Atividade_estruturas_complementares, on_delete=models.PROTECT,
related_name='atividade_estruturas_complementares')
comprimento = models.DecimalField(
'Comprimento', max_digits=10, decimal_places=2, blank=True, null=True, default=None)
largura_altura = models.DecimalField(
'Largura / Altura', max_digits=6, decimal_places=2, blank=True, null=True)
profundidade = models.DecimalField(
'Profundidade', max_digits=10, decimal_places=2, blank=True, null=True, default=None)
valor = models.FloatField(default=0.0)
class Meta:
verbose_name = 'Estrutura Complementar'
verbose_name_plural = 'Estruturas Complementares'
unique_together = (('passivo_id', 'atividade_complementar'),)
def __str__(self):
return ''
class Foto(models.Model):
property = models.ForeignKey(Passivo,
related_name='fotos',
on_delete=models.CASCADE, null=True) # , default='no-img.png')
image = ImageWithThumbsField(sizes=((100, 130), (200, 260)))
descricao = models.CharField(
'Descrição', max_length=300, blank=True, null=True, default=None)
class Meta:
verbose_name_plural = "Fotos"
def __str__(self):
return ("Fotos do passivo"
admin py.
from django.contrib import admin
from django.apps import apps
from .models import Feicao, Passivo, Causa, Consequencia, Foto, Local, Unidade, Atividade, Reparo, \
Estruturas_complementares, Protecao_superficial, Atividade_estruturas_complementares, \
Atividade_protecao_superficial, Abrangencia, Magnitude, Interferencia
from sorl.thumbnail.admin import AdminImageMixin
import nested_admin
from leaflet.admin import LeafletGeoAdmin
from jet.admin import CompactInline
class ReparoInline(nested_admin.NestedTabularInline):
model = Reparo
extra = 0
class FotoInline(AdminImageMixin, nested_admin.NestedTabularInline):
model = Foto
extra = 0
class LocalInline(nested_admin.NestedTabularInline):
model = Local
extra = 0
class Estruturas_complementares_inline(nested_admin.NestedTabularInline):
model = Estruturas_complementares
readonly_fields = ('valor',)
extra = 0
class Protecao_superficial_inline(nested_admin.NestedTabularInline):
model = Protecao_superficial
readonly_fields =('valor',)
extra = 0
class PassivoAdmin(nested_admin.NestedModelAdmin, LeafletGeoAdmin):
model = Passivo
list_filter = ['data_inspecao']
autocomplete_fields = ['metodos_reparo', 'possiveis_causas', 'provaveis_consequencias',]
list_display = ('id', 'segmento_rodoviario', 'km_ponto',
'lado', 'latitude', 'longitude', 'estado')
readonly_fields = ('segmento_rodoviario', 'indice_prioridade', 'estado',
'municipio', 'modelo_3d_path','valor_total_reparo')
fieldsets = (
(None, {
'fields': ('data_inspecao',)
}),
('Localização', {
'fields': ('latitude', 'longitude', 'km_ponto', 'lado', 'distancia_ao_eixo', 'area_ocorrencia_faixa_dominio', 'area_ocorrencia_area_adjacente')
}),
('Mapa', {
'fields': ('localizacao',)
}),
('Segmento Rodoviário', {
'classes': ('collapse',),
'fields': ('largura_faixa_dominio_esquerda', 'largura_faixa_dominio_direita', 'pista_rolamento_numero', 'pista_rolamento_pavimento', 'acostamento_presenca', 'terceira_faixa_localizacao', 'relevo')
}),
('Caracterização', {
'classes': ('collapse',),
'fields': ('feicao', 'risco_ao_usuario', 'risco_ao_patrimonio', 'risco_ao_ambiente', 'possiveis_causas', 'provaveis_consequencias', 'abrangencia', 'magnitude', 'interferencia','indice_prioridade', 'modelo_3d', 'modelo_3d_path', 'croqui', 'observacoes', 'segmento_rodoviario', 'estado', 'municipio')
}),
('Métodos de Reparo', {
'classes': ('collapse',),
'fields': ('metodos_reparo', 'dimensao_comprimento', 'largura_faixa_dominio_total', 'dimensao_profundidade', 'valor_total_reparo')
}),
)
inlines = [Estruturas_complementares_inline, Protecao_superficial_inline, FotoInline, LocalInline]
Edit:
I started testing yesterday the following way:
def calcula_valor(sender, **kwargs):
if kwargs['created']:
atividade = Passivo.objects.update(id=kwargs['instance'])
atividade.valor = calculoSuperficial(atividade.atividade_superficial,atividade.comprimento,atividade.largura_altura,atividade.profundidade, atividade.passivo_id)
elif kwargs['update_fields']:
atividade = Protecao_superficial.objects.create(passivo_id=kwargs['instance'])
atividade.valor = calculoSuperficial(atividade.atividade_superficial,atividade.comprimento,atividade.largura_altura,atividade.profundidade, atividade.passivo_id)
else:
for atividade in Protecao_superficial.objects.all().filter(passivo_id_id=kwargs['instance']):
valor = calculoSuperficial(atividade.atividade_superficial,atividade.comprimento,atividade.largura_altura,atividade.profundidade, atividade.passivo_id)
atividade.valor = valor
atividade.save() # Edit2: como descrito era apenas o .save() e a solução funcionou
post_save.connect(calcula_valor, sender=Passivo)
It almost worked, I can access all the objects I need, I do the calculations, but when saving the changes are not being saved, as far as I could see, I am not able to attach the information to the context.
Hello alive take a look here For example, if it becomes too complex, share more details about your models.py and admin.py with what you’ve done so far. Another suggestion, or plan B would be to create a Trigger, not recommend the use of triggers in some cases cause performance problems, if it is a table with little data in this particular case may be a solution, i.e. when recording into Liability Trigger is triggered and performs the operation you want.
– Ernesto Casanova
Hi, improved. But you can put pf the objects of the models that are in admin, so it’s just copy and Paste and I have your scenario
– Ernesto Casanova
I’ll do it now
– Neto Miranda