Skip to content

Instantly share code, notes, and snippets.

@PirosB3
Created March 18, 2014 00:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PirosB3/9611350 to your computer and use it in GitHub Desktop.
Save PirosB3/9611350 to your computer and use it in GitHub Desktop.
from bisect import bisect
from django.utils import six
from django.db.models import signals
from django.db import models
from django.db.models.manager import *
from django.db.models.fields import FieldDoesNotExist
from django.apps import apps
from pymongo import MongoClient
class MongoQuerySet(object):
def __init__(self, model=None, query=None, using=None, hints=None):
self.model = model
self.using = using
self.table = self.model._meta.db_table
def count(self):
return self.using[self.table].count()
class MongoManager(Manager):
client = MongoClient()['ducks']
def get_queryset(self):
return MongoQuerySet(self.model, using=self.client)
class DuckOptions(object):
@property
def fields(self):
return [f for f in self.local_fields]
@property
def concrete_fields(self):
return [f for f in self.fields if f.column is not None]
def get_field_by_name(self, name):
for f, model in self.get_fields_with_model():
if name in [f.name, f.attname]:
f, model, True, False
def get_concrete_fields_with_model(self):
return [(f, None) for f in self.concrete_fields]
def get_fields_with_model(self):
return [(f, None) for f in self.local_fields]
def get_field(self, name, m2m=True):
to_search = self.local_fields
for f in to_search:
if f.name == name:
return f
raise FieldDoesNotExist('%s has no field named %r' % (self.object_name, name))
def setup_pk(self, field):
if not self.pk and field.primary_key:
self.pk = field
field.serialize = False
def add_field(self, field):
self.local_fields.insert(bisect(self.local_fields, field), field)
self.setup_pk(field)
def _prepare(self, model):
auto = models.AutoField(verbose_name='ID', primary_key=True,
auto_created=True)
model.add_to_class('id', auto)
if not self.db_table:
self.db_table = "%s_%s" % (self.app_label, self.model_name)
db_table = None
concrete_managers = []
local_fields = []
abstract = False
app_label = "duck"
pk = None
ordering = []
verbose_name_plural = "Ducks"
model_name = "ducks"
swapped = False
has_auto_field = False
object_name = "duck"
apps = apps
# ModelBase
class DuckMeta(type):
def __new__(cls, name, bases, attrs):
cls._meta = DuckOptions()
for name, field in [('name', models.CharField(max_length=250)),
('objects', MongoManager()),
('age', models.PositiveIntegerField())]:
field.contribute_to_class(cls, name)
cls._meta._prepare(cls)
signals.class_prepared.send(sender=cls)
return cls
@classmethod
def add_to_class(cls, name, value):
if hasattr(value, 'contribute_to_class'):
value.contribute_to_class(cls, name)
else:
setattr(cls, name, value)
# Model
class DuckBase(six.with_metaclass(DuckMeta, object)):
pass
# MY MODEL!
class Duck(DuckBase):
pass
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment