2013-03-18 15 views
6

Voglio avere un modello con 2 campi, figli e genitore. Come faccio a fare questo in django? Ho qualcosa di simileRealizzare una struttura ad albero in modelli django?

from django.db import models 
class FooModel(models.Model) 
    parent = models.ForeignKey('self', blank=True, null=True) 
    children = models.ManyToOneRel('self', blank=True, null=True) 

    def __init__(self, *args, **kwargs): 
     super(FooModel, self).__init__(*args, **kwargs) 
     self.parent.children.add(self) 

Ma non credo che dovrei usare il ManyToOneRel come questo (soprattutto perché mi sta dando un errore di parola chiave su 'vuoto'). Qualche consiglio?

+5

https://github.com/django-mptt/django-mptt/ – dm03514

+1

https://tabo.pe/projects/django-treebeard/docs/1.61/api.html – andrefsp

+0

Queste sono entrambe molto belle, ma è possibile farlo direttamente nei campi come sto cercando di fare sopra? Preferirei non includere un'altra dipendenza in questo, e non mi interessa molto l'efficienza in questo caso. – sfendell

risposta

17

ManyToOneRel è una classe di implementazione interna, non è utilizzabile nei modelli.

Ma perché pensi di averne bisogno comunque? Come la documentazione spiega in dettaglio, quando si definisce un ForeignKey, si ottiene automaticamente una relazione inversa. Quindi nel tuo caso, se si definisce parent quindi si ottiene automaticamente self.foomodel_set già: e si può rendere ancora più esplicito utilizzando il parametro related_name:

parent = models.ForeignKey('self', blank=True, null=True, related_name='children') 

Si noti che se si sta progettando di fare le cose complicate con alberi , probabilmente vorrai usare la libreria django-mptt.

0

non riuscivo a trovare la documentazione per ManyToOneRel così ho guardato il code for it:

def __init__(self, to, field_name, related_name=None, limit_choices_to=None, 
     parent_link=False, on_delete=None): 

Come si può vedere, non c'è blank argomento.

+0

Giusto, l'ho già capito. Mi chiedo invece cosa dovrei usare. – sfendell

+0

forse basta usare un CharField per memorizzare le chiavi dei bambini e un metodo o una proprietà personalizzata per istanziarli su richiesta? –

2
class FooModel(models.Model) 
    parent = models.ForeignKey('self', blank=True, null=True, related_name='children') 


FooModel.objects.get(pk=1).children.all() 

Se si desidera memorizzare nella cache uso quello che vuoi: la cache di interrogazione da qualche parte, memorizzare tutti i bambini in padre come una semplice lista di PKS, ma non dimenticare di gestire nuove entità di aggiornare questa lista. ManyToOneRel è per esigenze interne di django inoltre non è un'istanza di classe Field.

Problemi correlati