[Django models] - Como relacionar models de diferentes apps?

767 views
Skip to first unread message

Marcos Luiz Wilhelm

unread,
Aug 8, 2013, 12:27:14 PM8/8/13
to django...@googlegroups.com
Olá pessoal!

Gostaria de uma sugestão quanto a melhor prática para criação de models.
Estou desenvolvendo um sistema de gerenciamento de repertórios e músicas.
Tenho até então um único modelo para todas as entidades:

# -*-encoding: utf-8 -*-
from django.db import models

class Location(models.Model):
name = models.CharField(max_length=200)
adress = models.CharField(max_length=500)
def __unicode__(self):
return self.name

class EventType(models.Model):
name = models.CharField(max_length=200)
def __unicode__(self):
return self.name

class Event(models.Model):
location = models.ForeignKey(Location)
eventType = models.ForeignKey(EventType)
name = models.CharField(max_length=200)
startDate = models.DateTimeField('data de início')
endDate = models.DateTimeField('data de término')
#alterar posteriormente para campo de upload.
projectionFile = models.CharField(max_length=200)
def __unicode__(self):
return self.name

class Author(models.Model):
completeName = models.CharField(max_length=200)
def __unicode__(self):
return self.completeName

class MusicCathegory(models.Model):
eventType = models.ForeignKey(EventType)
name = models.CharField(max_length=200)
def __unicode__(self):
return self.name

class LiturgicalTime(models.Model):
name = models.CharField(max_length=200)
def __unicode__(self):
return self.name

class LiturgicalYear(models.Model):
name = models.CharField(max_length=200)
def __unicode__(self):
return self.name

class Music(models.Model):
MUSIC_STATUS = ((0,'Suspended'), (1,'Approved'))
musicStatus = models.SmallIntegerField(choices=MUSIC_STATUS)
author = models.ForeignKey(Author)
musicCathegories = models.ManyToManyField(MusicCathegory)
liturgicalTimes = models.ManyToManyField(LiturgicalTime)
liturgicalYears = models.ManyToManyField(LiturgicalYear)
name = models.CharField(max_length=200)
firstPhrase = models.CharField(max_length=200)
tone = models.CharField(max_length=5)
cipherFile = models.CharField(max_length=200)
scoreFile = models.CharField(max_length=200)
tabsFile = models.CharField(max_length=200)
audioFile = models.CharField(max_length=200)
videoOrAudioURL = models.CharField(max_length=300)
def __unicode__(self):
return self.name

class Repertory(models.Model):
REPERTORY_STATUS = ((0,'Suspended'), (1,'Approved'))
musics = models.ManyToManyField(Music)
repertoryStatus = models.SmallIntegerField(choices=REPERTORY_STATUS)
event = models.ForeignKey(Event)
name = models.CharField(max_length=200)
def __unicode__(self):
return self.name

Qual seria a melhor prática? criar três apps com suas models?
Eu pensei em separar por apps: "event", "repertory" e "music". Mas se eu criar dessa forma, como eu relaciono todas estas models para que uma veja a outra e estabeleça relacionamentos? 
Desde já agradeço quem puder me ajudar!

Atenciosamente,
Marcos.

Arthur Furlan

unread,
Aug 8, 2013, 1:08:33 PM8/8/13
to django...@googlegroups.com
No seu caso, eu manteria essas entidades dentro da mesma aplicação
pois eles são o core do seu projeto.

Apesar disso ser meio polêmico, IMHO separo aplicações quando acontece
1 dos casos abaixo:

1) Faz parte do projeto o código ser extremamente modular
2) O código não pertence ao core da sua aplicação
3) O código tem uma função muito específica dentro do projeto
4) Eu ou outra pessoa vai precisar reutilizar esse código (liberar
como open-source, por exemplo)


Além disso, você pode utilizar Generic Relations[1] para relacionar
models de diferentes aplicações.

[1]. https://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/#id1


-- Arthur Furlan


2013/8/8 Marcos Luiz Wilhelm <marcos...@gmail.com>:
> --
> Você está recebendo esta mensagem porque se inscreveu no grupo "Django
> Brasil" dos Grupos do Google.
> Para cancelar a inscrição neste grupo e parar de receber seus e-mails, envie
> um e-mail para django-brasi...@googlegroups.com.
> Para obter mais opções, acesse https://groups.google.com/groups/opt_out.
>
>

Fábio Cerqueira

unread,
Aug 8, 2013, 1:09:12 PM8/8/13
to django Brasil
As ForeignKey aceitam string para o nome do model. Ou você pode usar imports


2013/8/8 Marcos Luiz Wilhelm <marcos...@gmail.com>
Olá pessoal!

--
Você está recebendo esta mensagem porque se inscreveu no grupo "Django Brasil" dos Grupos do Google.
Para cancelar a inscrição neste grupo e parar de receber seus e-mails, envie um e-mail para django-brasi...@googlegroups.com.
Para obter mais opções, acesse https://groups.google.com/groups/opt_out.
 
 



--
Fábio Cerqueira

Marcos Luiz Wilhelm

unread,
Aug 8, 2013, 9:17:22 PM8/8/13
to django...@googlegroups.com
Valeu pessoal!
Vou manter numa model só como sugerido pelo Arthur.
Abraço!

Guilherme David da Costa

unread,
Aug 11, 2013, 4:20:15 AM8/11/13
to django...@googlegroups.com
Já foi respondido, mas gostaria de dar minha opinião caso possa ajudar outras pessoas.

Concordo com o Arthur, mas acho que de repente utilizar generic relations não é a melhor
saida em casos de OneToOneField pois voce terá que acessar o RelatedManager cada vez
que quiser busca-los e aquele .all[0] sendo visto no código pra buscar o que poderia ser um
OneToOneField pode deixa-lo feio.

O que o Fábio disse em utilizar imports é uma maneira mais limpa de fazê-lo na minha opinião
e respondendo a sua pergunta levando em conta as informações:

Você disse que pensou em separar por "event", "repertory" e "music".
Achei interessante, mas pensando bem, voce não teria muitas opções em questão do que
colocar em uma app chamada repertory, a não ser uma view onde o artista adiciona o seu
repertório (a não ser que eu esteja errado). Neste caso, seria legal fazer dividir em 2 apps
apenas: "events" e "musics" no plural, pois ao meu ver "events" está muito parecido com
um módulo a mais que seu projeto teria e "musics" aparenta ser o coração do projeto, ficando
com uma disponibilização de diretórios da seguinte maneira:

myproject/
    manage.py
    music/
        apps/
            musics/
                __init__.py
                views.py
                models.py
                ...
            events/
                __init__.py
                views.py
                models.py
                ...
        __init__.py
        settings.py
        ...

Neste exemplo, para um model ver o outro, basta a utilização do que é mais básico no python
e também apontado pelo Fábio: imports

Vou demonstrar em 1 exemplo:
# dentro de models.py na app events
from music.apps.musics.models import Author

class Event(models.Model):
    name = models.CharField()
    participants = models.ManyToManyField(Author)

# dentro de models.py na app musics
class Author(models.Model):
    name = models.CharField()

python trata todo e qualquer diretório com um __init__.py dentro como um package, permitindo
ao desenvolvedor chamá-lo utilizando um import. Isso é uma das facas de dois gumes que
existem no python ao se usar django, pois voce pode colocar seus models onde quiser e a
arquitetura do seu projeto vai ficar difícil de ser reconhecida por outros programadores. Siga
um padrão e voce verá que isso vai te ajudar bastante na organização.

Espero ter sido útil e não ter me prolongado demais nesta mensagem.



2013/8/8 Marcos Luiz Wilhelm <marcos...@gmail.com>
Valeu pessoal!

--
Você está recebendo esta mensagem porque se inscreveu no grupo "Django Brasil" dos Grupos do Google.
Para cancelar a inscrição neste grupo e parar de receber seus e-mails, envie um e-mail para django-brasi...@googlegroups.com.
Para obter mais opções, acesse https://groups.google.com/groups/opt_out.
 
 



--
my e-mail composition:
80% -> garbage
9%   -> serious
11% -> me doesn't making any sense

Reply all
Reply to author
Forward
0 new messages