Skip to content

Instantly share code, notes, and snippets.

@gustavofonseca
Created March 22, 2014 22:55
Show Gist options
  • Save gustavofonseca/9715760 to your computer and use it in GitHub Desktop.
Save gustavofonseca/9715760 to your computer and use it in GitHub Desktop.
Abordagem evitando o relacionamento ternário.
"""
>>> rsp = models.Journal.objects.create(title=u'Revista de saúde pública')
(0.002) INSERT INTO "journalmanager_journal" ("title") VALUES (Revista de saúde pública); args=[u'Revista de sa\xfade p\xfablica']
>>>
>>> brasil = models.Collection.objects.create(name=u'Brasil')
(0.001) INSERT INTO "journalmanager_collection" ("name") VALUES (Brasil); args=[u'Brasil']
>>>
>>> rsp.join(brasil)
(0.001) INSERT INTO "journalmanager_membership" ("journal_id", "collection_id", "publication_status", "publication_status_since") VALUES (1, 1, c, 2014-03-22 22:47:59.174742); args=[1, 1, 'c', u'2014-03-22 22:47:59.174742']
(0.001) INSERT INTO "journalmanager_journaltimeline" ("journal_id", "collection_id", "publication_status", "publication_status_since") VALUES (1, 1, c, 2014-03-22 22:47:59.174742); args=[1, 1, 'c', u'2014-03-22 22:47:59.174742']
>>>
>>> rsp.change_status(brasil, 'd')
(0.000) SELECT "journalmanager_membership"."id", "journalmanager_membership"."journal_id", "journalmanager_membership"."collection_id", "journalmanager_membership"."publication_status", "journalmanager_membership"."publication_status_since" FROM "journalmanager_membership" WHERE ("journalmanager_membership"."journal_id" = 1 AND "journalmanager_membership"."collection_id" = 1 ); args=(1, 1)
(0.000) SELECT (1) AS "a" FROM "journalmanager_membership" WHERE "journalmanager_membership"."id" = 1 LIMIT 1; args=(1,)
(0.001) UPDATE "journalmanager_membership" SET "journal_id" = 1, "collection_id" = 1, "publication_status" = d, "publication_status_since" = 2014-03-22 22:48:15.571127 WHERE "journalmanager_membership"."id" = 1 ; args=(1, 1, 'd', u'2014-03-22 22:48:15.571127', 1)
(0.000) SELECT "journalmanager_journal"."id", "journalmanager_journal"."title" FROM "journalmanager_journal" WHERE "journalmanager_journal"."id" = 1 ; args=(1,)
(0.000) SELECT "journalmanager_collection"."id", "journalmanager_collection"."name" FROM "journalmanager_collection" WHERE "journalmanager_collection"."id" = 1 ; args=(1,)
(0.000) INSERT INTO "journalmanager_journaltimeline" ("journal_id", "collection_id", "publication_status", "publication_status_since") VALUES (1, 1, d, 2014-03-22 22:48:15.571127); args=[1, 1, 'd', u'2014-03-22 22:48:15.571127']
>>>
>>> rsp.membership_info(brasil, 'publication_status')
(0.000) SELECT "journalmanager_membership"."id", "journalmanager_membership"."journal_id", "journalmanager_membership"."collection_id", "journalmanager_membership"."publication_status", "journalmanager_membership"."publication_status_since" FROM "journalmanager_membership" WHERE ("journalmanager_membership"."journal_id" = 1 AND "journalmanager_membership"."collection_id" = 1 ); args=(1, 1)
u'd'
>>>
>>> rsp.statuses.all()
(0.000) SELECT "journalmanager_journaltimeline"."id", "journalmanager_journaltimeline"."journal_id", "journalmanager_journaltimeline"."collection_id", "journalmanager_journaltimeline"."publication_status", "journalmanager_journaltimeline"."publication_status_since" FROM "journalmanager_journaltimeline" WHERE "journalmanager_journaltimeline"."journal_id" = 1 LIMIT 21; args=(1,)
[<JournalTimeline: JournalTimeline object>, <JournalTimeline: JournalTimeline object>]
"""
from django.db import models
class Journal(models.Model):
collections = models.ManyToManyField('Collection',
through='Membership', related_name='journals')
title = models.CharField(max_length=32)
def join(self, collection):
"""Make this journal part of the collection.
"""
Membership.objects.create(journal=self,
collection=collection,
publication_status='c')
def membership_info(self, collection, attribute=None):
"""Retrieve info about the relation of this journal with a
given collection.
"""
rel = self.membership_set.get(collection=collection)
if attribute:
return getattr(rel, attribute)
else:
return rel
def change_status(self, collection, new_status):
rel = self.membership_info(collection)
rel.publication_status = new_status
rel.save()
class Collection(models.Model):
name = models.CharField(max_length=32)
def add_journal(self, journal):
journal.join(self)
class Membership(models.Model):
"""
Represents the many-to-many relation
between Journal and Collection.
"""
journal = models.ForeignKey('Journal')
collection = models.ForeignKey('Collection')
publication_status = models.CharField(max_length=1,
choices=[('c', 'current'), ('d', 'deceased')])
publication_status_since = models.DateTimeField(auto_now=True)
def save(self, *args, **kwargs):
"""
Always save a copy at JournalTimeline
"""
super(Membership, self).save(*args, **kwargs)
JournalTimeline.objects.create(journal=self.journal,
collection=self.collection,
publication_status=self.publication_status,
publication_status_since=self.publication_status_since)
class JournalTimeline(models.Model):
"""
Represents the status history of a journal.
"""
journal = models.ForeignKey('Journal', related_name='statuses')
collection = models.ForeignKey('Collection')
publication_status = models.CharField(max_length=1,
choices=[('c', 'current'), ('d', 'deceased')])
publication_status_since = models.DateTimeField()
@fabiobatalha
Copy link

Me parece bom. No caso o StatusParty morre. Não encontrei referência para statuses na linha 12.

@fabiobatalha
Copy link

Eu até tinha pensado nisso na hora que escrevi no papel, mas não soube explicar direito.

@fabiobatalha
Copy link

Eu acho que teremos que começar o model-overhaul do zero :-/ mas tudo bem.

@gustavofonseca
Copy link
Author

faz parte =]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment