example - django override save
DB/performance: diseño del modelo django que rara vez se refiere a su padre más de una vez (2)
Tengo una aplicación que trata de presentar ciudades ficticias simplificadas.
Por favor considere los siguientes modelos de Django:
class City(models.Model):
name = models.CharField(...)
...
TYPEGROUP_CHOICES = (
(1, ''basic''),
(2, ''extra''),
)
class BldgType(models.Model):
name = models.CharField(...)
group = models.IntegerField(choices=TYPEGROUP_CHOICES)
class Building(models.Model):
created_at = models.DateTimeField(...)
city = models.ForeignKey(City)
type = models.ForeignKey(BldgType)
other_criterion = models.ForeignKey(...)
class Meta:
get_latest_by = ''created_at''
Explicaciones para elegir esta configuración:
(1) Cada ciudad tiene ciertos edificios de tipo "básico" que ocurren exactamente una vez por ciudad (ejemplos: ayuntamiento, estación de bomberos, estación de policía, hospital, escuela) y posiblemente docenas de edificios de tipo "extra", como el baile. clubs.
(2) En ciertas vistas, todos los edificios (independientemente de la ciudad, etc.) se deben filtrar según diferentes criterios, por ejemplo, other_criterion
.
Problema / preocupación:
En una vista de city_detail
, tendría que pasar por encima de cualquier edificio de tipo "extra", lo cual está bien y es normal.
Pero no estoy seguro de cómo recuperar eficientemente el edificio "hospitalario" de la ciudad, que es de tipo "básico", así que debo hacer esto para todas las ciudades porque en cada ciudad existe exactamente un hospital de este tipo (esto está asegurado en el momento de la creación de la ciudad )
Habrá como máximo una docena de tipos de edificios "básicos", de los cuales aproximadamente la mitad se presentarán todo el tiempo.
Me inclino por escribir métodos de conveniencia en el modelo de la ciudad, y tengo tres opciones:
(A1) A través de try
and index: .filter(...)[0]
(A2) a través de try
y .get(...)
(A3) a través de try
y .filter(...).latest()
Pero ninguno de esos parece elegante. ¿O es una buena opción combinar estas tres opciones con algún tipo de almacenamiento en caché, como en el método get_profile()
Django en el modelo de User
? Lamentablemente, todavía no tengo experiencia con el almacenamiento en caché.
¿Es loco usar la siguiente opción?
(B) FK específicos en el modelo de la ciudad, uno para cada uno de los tipos básicos más importantes
Pregunta:
¿Qué opción tiene más sentido?
¿O es el esquema generalmente defectuoso para este tipo de escenario?
Especialmente con respecto al rendimiento de DB, ¿qué sugieres? ¿Necesito un enfoque completamente diferente?
¡Por favor avise! :)
¡Gracias por adelantado!
Si una ciudad no puede tener más de uno cada uno de ayuntamiento, estación de bomberos, estación de policía, hospital, escuela, etc., entonces creo que la forma más directa de hacer cumplir esto es declarar cada uno como un campo en el modelo:
class City(models.Model):
name = models.CharField(...)
city_hall = models.ForeignKey(Building)
fire_station = models.ForeignKey(Building)
# ... et cetera
Si le parece demasiado "desordenado" en su modelo de ciudad, puede considerar tener un modelo intermedio de CityBuildings
:
class CityBuildings(models.Model):
city_hall = models.ForeignKey(Building)
fire_station = models.ForeignKey(Building)
# ... et cetera
class City(models.Model):
name = models.CharField(...)
buildings = models.OneToOneField(CityBuildings)
Luego se refiere a edificios como, por ejemplo, city.buildings.fire_station
Estas son solo sugerencias ... No estoy seguro si de alguna manera es más "correcto"
Para cualquiera que esté interesado: tonto me descubrió la existencia de la técnica de memorización, así que usaré alguna forma de eso aplicado a (A2), envuelto en tantos métodos de conveniencia en el modelo de Ciudad como tengo tipos de construcción "básicos".
Esto es al menos menos complicado que tener FK en dos direcciones y permite que el código sea más claro sobre la separación de intereses (modelado por un lado, rendimiento por el otro).
Rápidamente, distinguí dos proyectos para estudiar y posiblemente prestar o aplicar directamente:
- django-memoize
- github.com/husio/django-easycache/
Quizás alguien encuentre esto útil también.