2016-06-09 13 views
1

Ich habe ein Setup, wo ich mehrere Modelle haben, von denen zwei Option und Project sind. Options stellen Auswahloptionen für mehrere Felder in meiner Anwendung dar und speichern ungefähr 1000 (Standard) Werte. Was ich jetzt erreichen möchte, ist, dass Projects ihren eigenen Satz von Options haben kann, das bedeutet, dass sie den Standardsatz der Optionen sehen werden, wenn sie einen neuen Project starten. Allerdings können sie löschen einige Optionen, die dann nicht in ihrem Projekt angezeigt werden (aber in der Datenbank bleiben) sowie hinzufügen benutzerdefinierte Optionen zu ihrem Projekt (die andere sollte nicht in der Lage sein zu sehen). Der allgemeine Anwendungsfall ist, dass Benutzer 99% des Standardwerts Options beibehalten möchten, sodass sie 10 löschen und möglicherweise 10 hinzufügen.Django Modell Viele zu viele Alternative

Wie modelliere ich den beschriebenen Fall? Müsste ich ein ManyToMany-Feld Project <-> Option haben, das ich mit allen Options bei der Projekt-Erstellung füllen würde oder gibt es eine bessere, weniger Platz verbrauchende Weise, die Sie sich vorstellen können, z. Irgendwie irgendwo gelöschte IDs speichern und einen Weg finden, den Standard Options + projektspezifisch Options anzuzeigen?

Meine Modelle sind wie folgt:

class Option(models.Model): 
    creator = models.ForeignKey(settings.AUTH_USER_MODEL, related_name="selectoptions", blank=True, null=True) 
    created = models.DateField(auto_now_add=True) 
    deleted = models.BooleanField(default=False) 

    name = models.CharField(max_length=255) 

    #we can have nested selectoptions 
    parent = models.ForeignKey('self', blank=True, null=True, related_name='children', db_index=True) 

class Project(models.Model): 
    name = models.CharField(max_length=200) 
    users = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='projects') 

Antwort

2

Sie können Ihre Projektmodell als solche

class Project(models.Model): 
    name = models.CharField(max_length=200) 
    options = models.ManyToManyField(Option, blank=True) 
    anyother field you wish to have 

und Sie können mit der Option Modell Sie haben, das sollte genügen müssen fortgesetzt werden.

Jetzt können sagen, Sie haben Optionen 1,2,3,4,5 und Projekte A und B

A Optionen 1,2,3 und B haben können 2,3 Optionen, 4,5.

Des Weiteren müssen Sie nicht die Option 1 in Ihrem Projekt A haben wollen, können Sie es einfach aus M2M Bereich dieser

Anweisung entfernen
projectA.options.remove(option1) 

So haben Sie gelöscht option1 aus dem Projekt, aber es bleibt noch in der Datenbank, können Sie gleiche option1 zu ProjectB hinzufügen, indem Anweisung

projectB.options.add(option1) 

So, jetzt, wenn Sie tun

projectA.options.all() 

Ihr Ausgang wird OPTION2, option3

und projectB.options.all() geben option1, option2, option3, option4, Option5.

Ich hoffe, ich habe richtig erklärt, falls es unklar ist, hinterlassen Sie einen Kommentar, wird glücklich sein, zu helfen.

Bearbeiten: und ja das ist, wie es in Ihrem Fall sein sollte, es sei denn, Sie erhalten alternative Möglichkeit, es zu tun.

Edit 2:

Beitrag der Frage zu aktualisieren, können Sie die Optionen als M2M Bereich von Projekt entfernen und ein separates Modell mit Namen ProjectOption haben. Es kann sein,

class ProjectOption(models.Model): 
    project = models.ForeignKey(Project) 
    option = models.ForeignKey(Option) 
    is_deleted = models.BooleanField(default=False) 

Sie müssen immer noch füllen, es ist eine einmalige Operation für Sie. So, jetzt haben Sie Ihre Standard-Optionen pro Projekt, wenn Benutzer beschließt, einen zu löschen, können Sie entweder is_deleted = True setzen oder es tatsächlich löschen. Dadurch erhalten Sie Details zu Optionen, die gelöscht werden (nur wenn Sie kein Objekt löschen, sondern nur is_deleted = True).

+0

Das Problem ist, dass wenn ich ein neues Projekt erstellen würde, ich immer tun müsste: 'selectOptions = Option.objects.all() newProject.options.add (* selectOptions)' Das wäre ein riesiger Aufwand wie es würde Erstellen Sie Datenbankeinträge für alle Elemente. Ich würde es vorziehen, IDs von gelöschten selectoptions irgendwie zu speichern, und obendrauf möglicherweise nur selectOptions von Standardprojekt + selectOptions des aktuellen Projekts – niklas

+0

Kann ich wissen, wie ist das ein Problem? und warum Sie newProject.options.add (* selectOptions) tun müssen. Siehe, Optionen sind separate Entitäten. Wenn Sie ein neues Projekt erstellen, hat es keine Optionen, richtig? Also, seine M2M Optionen Feld wird nichts haben. Füllen Sie es nur auf, wenn der Benutzer diese Option hinzufügt. –

+0

Wenn Sie newProject.options.add (* selectOptions) ausführen, füllen Sie unnötigerweise newProject mit Optionen und bitten dann den Benutzer, unerwünschte zu entfernen, wenn es so sein sollte, wie der Benutzer hinzufügen/entfernen kann, was er will. –

Verwandte Themen