Pregunta

Tengo una aplicación que se trata de presentar ciudades simplificadas ficticias.

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 un "básico" tipo que ocurre exactamente una vez por ciudad (ejemplos: ayuntamiento, estación de bomberos, estación de policía, hospital, escuela) y posiblemente docenas de edificios de "extra" tipo, como clubes de baile.

(2) En ciertas vistas, todos los edificios (independientemente de la ciudad, etc.) se deben filtrar de acuerdo con diferentes criterios, por ejemplo, other_criterion .

Problem/concern:

En una vista city_detail , tendría que recorrer cualquier edificio de "extra". tipo, que está bien y es normal.

Pero no estoy seguro de cómo recuperar eficientemente el "hospital" de la ciudad edificio, que es de "básico" tipo, por lo que debo hacer esto para cada ciudad de todos modos porque existe exactamente uno de esos hospitales en cada ciudad (esto se garantiza en el momento de la creación de la ciudad).

Habrá a lo sumo una docena de "básico" tipos de edificios, de los cuales aproximadamente la mitad se presentarán todo el tiempo.

Me inclino por escribir métodos de conveniencia en el modelo City, y me enfrento a tres opciones:

(A1) Vía pruebe e indexe: .filter(...)[0font>

(A2) Vía pruebe y .get(...)

(A3) Vía pruebe y .filter(...).latest()

Pero ninguno de esos parece elegante. ¿O una de estas tres opciones es buena para combinar con algún tipo de almacenamiento en caché, como en el método get_profile () de Django en el modelo Usuario ? Lamentablemente, todavía no tengo experiencia con el almacenamiento en caché.

¿Es una locura usar la siguiente opción?

(B) FK específicos en el modelo City, uno para cada uno de los tipos básicos más importantes

Pregunta :

¿Qué opción tiene más sentido?
¿O el esquema es generalmente defectuoso para este tipo de escenario?

Especialmente con respecto al rendimiento de la base de datos, ¿qué sugieres? ¿Necesito un enfoque completamente diferente?

¡Por favor avise! :)

¡Gracias de antemano!

¿Fue útil?

Solución

Si una ciudad no puede tener más de uno en cada ayuntamiento, estación de bomberos, estación de policía, hospital, escuela, etc., 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 también encuentra esto '' desordenado '' en su modelo de ciudad, podría considerar tener un modelo intermedio 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 los edificios como, por ejemplo, city.buildings.fire_station

Estas son solo sugerencias ... No estoy seguro si alguna de las formas es más "correcta"

Otros consejos

Para cualquiera que esté interesado: tonto, descubrí la existencia de la técnica de memorización, por lo que utilizaré alguna forma de la aplicada a (A2), envuelta en tantos métodos de conveniencia en el modelo de Ciudad como tengo "básico". tipos de construcción.

Esto es al menos algo 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, realicé dos proyectos para estudiar para aprender y posiblemente prestar cosas o aplicar directamente:

  1. django-memoize
  2. github.com/husio/django-easycache/

Tal vez alguien encuentre esto útil también.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top