Skip to content

Instantly share code, notes, and snippets.

@raliste
Created July 25, 2011 21:52
Show Gist options
  • Save raliste/1105325 to your computer and use it in GitHub Desktop.
Save raliste/1105325 to your computer and use it in GitHub Desktop.
# Problema:
# Cada objeto de cualquier tipo puede tener relaciones (de referencia) con cualquier otro objeto de cualquier tipo.
# Se usara para relacionar contenido en el sitio. Por ejemplo:
# Proyecto X -> Oficina A, Usuario B, Evento C
# Y al mismo tiempo para sacar las relaciones "inversas", Oficina A -> Proyecto X; Usuario B -> Proyecto X y Evento C # -> Proyecto X
# El problema no es una relacion N:M tradicional, es mas bien una relacion de referencia más cercano a un digrafo (o grafo dirigido) (solo una hipotesis).
#
# Opción 1
#
"""
CREATE TABLE related_graph (
from_content_type_id INT NOT NULL,
from_object_id INT NOT NULL,
to_content_type_id INT NOT NULL,
to_object_id INT NOT NULL,
UNIQUE from_to(from_content_type_id,from_object_id,to_content_type_id,to_object_id)
)
"""
# Implementación de la opción 1 en Python/Django
class Project(models.Model):
# ...
def get_related_objects(self):
objects = RelatedGraph.objects.filter(from_id=self.id,
from_content_type_id=self.content_type_id)
ids = objects.values_list('from_id')
for id in ids:
# do something to get object’s data from memcache, render some html server side or
# anything
return objects
for object in Project.objects.filter(id=XXX).get().get_related_objects():
# do something
# Para crear una relacion
RelatedGraph.objects.add(from=Project, to=Instance_of_Anything)
class RelatedGraphManager(models.Manager):
def add(from_object, to_object, reverse=False):
from_id = from_object.get_related_id()
to_id = to_object.get_related_id()
self.create(from_id = from_object.id, from_content_type_id=from_object.content_type_id,
to_id = to_object.id, to_content_type_id=to_object.content_type_id)
if reverse:
elf.create(from_id = to_object.id, from_content_type_id=to_object.content_type_id,
to_id = from_object.id, to_content_type_id=from_object.content_type_id)
class RelatedGraph(models.Model):
# ...
objects = RelatedGraphManager()
#
# Opción 2
#
"""
CREATE TABLE related_objects (
id INT NOT NULL AUTO_INCREMENT,
content_type_id INT NOT NULL,
object_id INT NOT NULL,
PRIMARY KEY(id),
UNIQUE content_type_object(content_type_id, object_id)
) Engine = InnoDB;
CREATE TABLE related_graph (
from_id INT NOT NULL,
to_id INT NOT NULL,
UNIQUE from_to(from_id, to_id)
) Engine = InnoDB;
"""
# Implementación en Python/Django de la opción 2
class Project(models.Model):
# ...
def get_related_id(self):
object, created = RelatedObject.objects.get_or_create(self.content_type_id, self.id)
return object.id
def get_related_objects(self):
objects = RelatedGraph.objects.filter(from__id=self.get_related_id())
# do something to get object’s data from memcache, render some html server side or
# anything
return objects
for object in Project.objects.filter(id=XXX).get().get_related_objects():
# do something
# Para crear una relacion
RelatedGraph.objects.add(from=Project, to=Instance_of_Anything)
class RelatedGraphManager(models.Manager):
def add(from_object, to_object, reverse=False):
from_id = from_object.get_related_id()
to_id = to_object.get_related_id()
self.create(from_id = from_id,
to_id = to_id)
if reverse:
self.create(from_id = to_id,
to_id = from_id)
class RelatedGraph(models.Model):
# ...
objects = RelatedGraphManager()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment