2016-07-24 4 views
0

Also versuche ich eine gute Möglichkeit zu schaffen, sowohl "Häuser" als auch "Hausgruppen" zu modellieren.Eine bessere Art, zwei sehr ähnliche, aber unterschiedliche Objekte in Django darzustellen?

Häuser und Hausgruppen sind sehr ähnlich, da sie beide eine Beschreibung und Preisinformationen haben.

"Buchungen" können jedoch nur Häusern und nicht Hausgruppen zugewiesen werden.

Im Moment sieht mein Modell wie folgt aus:

class Houselike(models.Model): 
    max_guests = models.IntegerField() 
    name = models.CharField(max_length=20) 
    description = models.TextField(blank=True) 

class House(Houselike): 
    pass 

class HouseGroup(Houselike): 
    houses = models.ManyToManyField(House) 

Semantisch, das ist eigentlich ganz in der Nähe, was ich will. In der Datenbank führt dies jedoch dazu, dass es zwei Tabellen gibt, die beide nur ein einziges Feld "houselike_ptr_id" haben, das sich auf das "Hausartige" Basisobjekt bezieht.

Ob ein Hausobjekt ein Haus oder eine Hausgruppe ist, bedeutet also, in zwei verschiedene Tabellen zu schauen.

Eine effizientere Alternative zu tun wäre:

class Houselike(models.Model): 
    max_guests = models.IntegerField() 
    name = models.CharField(max_length=20) 
    description = models.TextField(blank=True) 
    is_group = models.BooleanField() 
    houses = models.ManyToManyField(House) 

Daraus ergibt sich nur ein zusätzliches Feld in der „MFH“ Tabelle und die andere Tabelle die dazugehörigen Häuser enthält, wird nur getroffen, wenn wir sie tatsächlich aussehen oben. Dies ist die beste Lösung aus Sicht der Speicher IMHO.

Dies ist jedoch aus semantischer Sicht nicht ganz so gut: Häuser und Housegroups sind ähnlich, aber unterschiedliche Objekte.

Dies ermöglicht auch Sachen wie Hausgruppen mit anderen Hausgruppen, Nicht-Gruppen mit Häusern, Dinge, die ich alle manuell überprüfen muss.

Ich mag es auch wirklich, mit House und HouseGroup Objekte explizit arbeiten zu können. Sie beide mit derselben Klasse zu repräsentieren, fühlt sich einfach falsch an.

Gibt es einen besseren Weg, dies zu tun?

EDIT:

Ich habe vergessen, dass die Preisinformationen (wie auch andere Einheiten) zu erwähnen, kann entweder mit einem Haus oder einem Housegroup zugeordnet sein und implementiert wird (grob) wie folgt:

class PricePeriod(models.Model): 
    house = models.ForeignKey(Houselike, on_delete=models.CASCADE) 
    arrival_date = models.DateField() 
    # Date of last departure date 
    departure_date = models.DateField() 
    price = models.DecimalField(max_digits = 10, decimal_places=2) 

Deshalb mache ich das Haus nicht einfach zu einem abstrakten Modell, weil diese anderen Objekte damit verwandt sind.

Antwort

0

Es stellt sich heraus, dass dies "Single-Table-Vererbung" genannt wird, die in meinem Fall perfekt ist.

Und dies ist das Internet, gibt es eine App dafür: https://github.com/craigds/django-typed-models

from typedmodels.models import TypedModel 

# Create your models here. 

class Houselike(TypedModel): 
    max_guests = models.IntegerField() 
name = models.CharField(max_length=20) 
description = models.TextField(blank=True) 

class House(Houselike): 
    pass 

class HouseGroup(Houselike): 
    houses = models.ManyToManyField(House) 

Das in so ziemlich führte genau das, was ich frage: eine einzelne Tabelle in der Datenbank, und ein explizite, semantisch korrekte Modell in Python/Django.

Jetzt muss ich nur meine schreckliche Benennung beheben ...

Verwandte Themen