2016-07-21 18 views
-1

Angenommen, Sie sind ein Verleger und haben mehrere Arten von Artikeln.Django wie man mehrere Varianten eines Modells erstellt

Standardartikel, gesponserten Artikel und Bewertung

Und gesponserte Artikel hat einige gesponserte geschützte Felder, sagen Sponsor und promotion_end_date

und Bewertung hat eine andere Bewertung nur Felder, wie zB Produktrücksendeadresse

Wie würdest du das gestalten?

Ich bin auf dieses Problem ein paar Mal gestoßen, und ich mache es immer in einem Modell mit allen verfügbaren Feldern, aber nicht erforderlich. Aber es fühlt sich einfach schlecht an, weil es bei den Administratoren Fehler macht. Was ist, wenn sie die Produktrücksendeadresse ausfüllen, aber keine Überprüfung? etc.

Und die meiste Zeit möchten Sie es in einem Modell, um die sehr ähnlichen Objekte zusammen abzufragen, da 90% des Fieldsets zwischen ihnen gleich ist. Und es ist sehr nützlich für Dinge wie die Suche nach beliebtesten

EDIT:

Diese Modelle werden fast immer zusammen abgefragt werden. Es macht also keinen Sinn, sie in verschiedene Tabellen zu legen und dann zu umgehen. Sie sollten in der gleichen Tabelle und indiziert sein. Sonst würde jede einzelne Anfrage 3x Anfragen machen, nicht eine. Und dann müssen die Abfragen anschließend rechnerisch zusammengeführt und sortiert werden.

+0

Mögliche Duplikat [Anzeigeobjekte aus verschiedenen Modelle auf der gleichen Seite nach ihrer Veröffentlichung Datum] (http://stackoverflow.com/questions haben/37747427/display-objects-from-different-models-auf-der-gleichen-Seite-entsprechend-ihrer-Publis) – e4c5

+0

Es ist kein Duplikat, weil dieser Post voraussetzt, dass Sie 3 verschiedene Modelle verwenden, und DANN das Optimieren des Abfrage. Ich frage, was ist der beste Weg, sehr ähnliche Modelle zu entwerfen, um Datenbankabfragen zu minimieren, was wahrscheinlich bedeutet, sie alle in einer Tabelle zu haben, wie 3 Modelle bedeutet 3x die Damen – straykiwi

Antwort

1

Sie können immer ein Basismodell haben, das von anderen nachfolgenden Modellen übernommen werden kann, die Sie benannt haben. In Ihrem Fall.

class BaseArticle(models.Model): 
    class Meta: 
     abstract = True 
    fields that are common to the models that will be inheriting this 


class StandardArticle(BaseArticle): 
    fields specific to StandardArticle 

Sie können andere Modelle in gleicher Weise wie StandardArticle

+0

Aber sie werden immer noch in separaten Datenbank sein Tabellen ANd und somit nicht zusammen abgefragt werden – straykiwi

+0

Natürlich können Sie nicht auf abstrakte Basisklassen abfragen. Sie können in Ihrem Fall tatsächlich eine konkrete Basisklasse verwenden. –

+0

Also, wenn Sie alle verschiedenen Arten zusammen abfragen müssen, wie würden Sie es tun? – straykiwi

1

Verwendung abstract base classes:

class ArticleBase(models.Model): 
    # fields 

    class Meta: 
     abstract = True 

class Article(ArticleBase): 
    pass 

class SponsoredArticle(ArticleBase): 
    # additional fields 

class Review(ArticleBase): 
    # additional fields 

Oder multi-table inheritance:

class Article(models.Model): 
    # fields 

class SponsoredArticle(Article): 
    # additional fields 

class Review(Article): 
    # additional fields 

Im letzteren Fall können Sie alle Abfrage articles mit Article.objects.select_related('sponsoredarticle', 'review').all() (können Sie benutzerdefinierte Manager erstellen select_related(...) jedes Mal zu vermeiden Eingabe). select_related() ist erforderlich, um eine DB-Abfrage beim Zugriff auf die untergeordnete Klasse zu vermeiden, z. G. aricle.review.