Come faccio a implementare un'interfaccia comune per i set di oggetti Django correlati?
-
21-08-2019 - |
Domanda
Ecco il punto:
Ho due modelli db, diciamo ShoppingCart
e Order
. Seguendo il principio DRY vorrei estrarre alcuni comuni puntelli / metodi in un'interfaccia condivisa ItemContainer
.
Tutto è andato bene fino a quando mi sono imbattuto il metodo _flush()
quali svolge principalmente eliminare su un insieme oggetto correlato.
class Order(models.Model, interface.ItemContainer):
# ...
def _flush(self):
# ...
self.orderitem_set.all().delete()
Quindi la domanda è: come faccio a sapere in modo dinamico wheter è orderitem_set
o shoppingcartitem_set
?
Soluzione
In primo luogo, qui ci sono due frammenti di Django che dovrebbe essere esattamente quello che stai cercando:
- eredità Modello con il tipo di contenuto e direttore eredità-aware
- ParentModel e ChildManager per modello di ereditarietà
In secondo luogo, si potrebbe desiderare di ripensare il vostro disegno e passare alla django.contrib tipi di contenuto quadro che ha una semplice .model_class()
metodo. (Il primo frammento di postato sopra anche utilizza il framework tipo di contenuto).
In terzo luogo, è probabilmente non vogliono usare l'ereditarietà multipla nella classe del modello. Non dovrebbe essere necessario e non sarei sorpreso se ci fosse qualche lato oscuro colpisce. Basta avere interface.ItemContainer
ereditare da models.Model
e poi Order
ereditare da solo <=>.
Altri suggerimenti
È possibile impostare l'argomento related_name di un ForeignKey, quindi se si desidera apportare modifiche minime al vostro disegno, si può solo avere ShoppingCartItem e OrderItem impostare lo stesso related_name sulle loro ForeignKeys a rispettivamente ShoppingCart and Order, (qualcosa come "item_set "):
order = models.ForeignKey(Order, related_name='item_set')
e
cart = models.ForeignKey(ShoppingCart, related_name='item_set')