def join_to_table( table, table2, table_field, table2_field, queryset, alias, extra_restriction_func=lambda where_class, alias, related_alias: None): """ Add a join on `table2` to `queryset` (having table `table`). """ foreign_object = ForeignObject(to=table2, from_fields=[None], to_fields=[None], rel=None) foreign_object.opts = Options(table._meta) foreign_object.opts.model = table foreign_object.get_joining_columns = lambda: ( (table_field, table2_field), ) foreign_object.get_extra_restriction = extra_restriction_func join = Join(table2._meta.db_table, table._meta.db_table, alias, LOUTER, foreign_object, True) queryset.query.join(join) # hook for set alias join.table_alias = alias queryset.query.external_aliases.add(alias) return queryset
def join_to(queryset, subquery, table_field, subquery_field, alias, join_type, nullable): """ Add a join on `subquery` to `queryset` (having table `table`). """ # here you can set complex clause for join def extra_join_cond(where_class, alias, related_alias): if (alias, related_alias) == ('[sys].[columns]', '[sys].[database_permissions]'): where = '[sys].[columns].[column_id] = ' \ '[sys].[database_permissions].[minor_id]' children = [ExtraWhere([where], ())] return where_class(children) return None table = queryset.model foreign_object = ForeignObject(to=subquery, on_delete=DO_NOTHING, from_fields=[None], to_fields=[None], rel=None) foreign_object.opts = Options(table._meta) foreign_object.opts.model = table foreign_object.get_joining_columns = lambda: ( (table_field, subquery_field), ) foreign_object.get_extra_restriction = extra_join_cond if isinstance(subquery.query, RawQuery): subquery_sql, subquery_params = subquery.query.sql, subquery.query.params else: subquery_sql, subquery_params = subquery.query.sql_with_params() join = CustomJoin(subquery_sql, subquery_params, table._meta.db_table, alias, join_type, foreign_object, nullable) # init first alias for this query queryset.query.get_initial_alias() # join subquery queryset.query.join(join) # hook for set alias join.table_alias = alias return queryset
class Contact(models.Model): company_code = models.CharField(max_length=1) customer_code = models.IntegerField() customer = ForeignObject( Customer, models.CASCADE, related_name="contacts", to_fields=["customer_id", "company"], from_fields=["customer_code", "company_code"], )
class Contact(models.Model): company_code = models.CharField(max_length=1) customer_code = models.IntegerField() customer = ForeignObject( Customer, models.CASCADE, related_name='contacts', to_fields=['customer_id', 'company'], from_fields=['customer_code', 'company_code'], )
class Child(models.Model): a = models.PositiveIntegerField() b = models.PositiveIntegerField() value = models.CharField(max_length=255) parent = ForeignObject( Parent, on_delete=models.SET_NULL, from_fields=('a', 'b'), to_fields=('a', 'b'), related_name='children', )
class Customer(models.Model): company = models.CharField(max_length=1) customer_id = models.IntegerField() address = ForeignObject( Address, models.CASCADE, null=True, # order mismatches the Contact ForeignObject. from_fields=["company", "customer_id"], to_fields=["company", "customer_id"], ) class Meta: unique_together = [("company", "customer_id")]
def join_to(table, subquery, table_field, subquery_field, queryset, alias): """ Add a join on `subquery` to `queryset` (having table `table`). """ # here you can set complex clause for join def extra_join_cond(where_class, alias, related_alias): if (alias, related_alias) == ('[sys].[columns]', '[sys].[database_permissions]'): where = '[sys].[columns].[column_id] = ' \ '[sys].[database_permissions].[minor_id]' children = [ExtraWhere([where], ())] return where_class(children) return None foreign_object = ForeignObject(to=subquery, from_fields=[None], to_fields=[None], rel=None, on_delete=models.DO_NOTHING) foreign_object.opts = Options(table._meta) foreign_object.opts.model = table foreign_object.get_joining_columns = lambda: ( (table_field, subquery_field), ) foreign_object.get_extra_restriction = extra_join_cond subquery_sql, subquery_params = subquery.query.sql_with_params() join = CustomJoin(subquery_sql, subquery_params, table._meta.db_table, alias, "LEFT JOIN", foreign_object, True) queryset.query.join(join) # hook for set alias join.table_alias = alias queryset.query.external_aliases.add(alias) return queryset
def join_to_queryset( table, subquery, table_field, subquery_field, queryset, alias, is_raw=False, extra_restriction_func=lambda where_class, alias, related_alias: None): """ Add a join on `subquery` to `queryset` (having table `table`). """ foreign_object = ForeignObject(to=subquery, from_fields=[None], to_fields=[None], rel=None, on_delete=models.CASCADE) foreign_object.opts = Options(table._meta) foreign_object.opts.model = table foreign_object.get_joining_columns = lambda: ( (table_field, subquery_field), ) foreign_object.get_extra_restriction = extra_restriction_func subquery_sql, subquery_params = ( subquery.query, []) if is_raw else subquery.query.sql_with_params() join = CustomJoin(subquery_sql, subquery_params, table._meta.db_table, alias, LOUTER, foreign_object, True) queryset.query.join(join) # hook for set alias join.table_alias = alias queryset.query.external_aliases.add(alias) return queryset
class AllFieldsModel(models.Model): big_integer = models.BigIntegerField() binary = models.BinaryField() boolean = models.BooleanField(default=False) char = models.CharField(max_length=10) csv = models.CommaSeparatedIntegerField(max_length=10) date = models.DateField() datetime = models.DateTimeField() decimal = models.DecimalField(decimal_places=2, max_digits=2) duration = models.DurationField() email = models.EmailField() file_path = models.FilePathField() floatf = models.FloatField() integer = models.IntegerField() generic_ip = models.GenericIPAddressField() null_boolean = models.NullBooleanField() positive_integer = models.PositiveIntegerField() positive_small_integer = models.PositiveSmallIntegerField() slug = models.SlugField() small_integer = models.SmallIntegerField() text = models.TextField() time = models.TimeField() url = models.URLField() uuid = models.UUIDField() fo = ForeignObject( 'self', on_delete=models.CASCADE, from_fields=['abstract_non_concrete_id'], to_fields=['id'], related_name='reverse' ) fk = ForeignKey( 'self', models.CASCADE, related_name='reverse2' ) m2m = ManyToManyField('self') oto = OneToOneField('self', models.CASCADE) object_id = models.PositiveIntegerField() # content_type = models.ForeignKey(ContentType, models.CASCADE) gfk = GenericForeignKey() gr = GenericRelation(DataModel)
app_label = 'tests' index_together = (('related', 'specific'), ) class TenantMeta: related_name = 'm2m_specifics' def test_mro(self): return 'M2MSpecific' ForeignObject( to=SpecificModel, on_delete=models.CASCADE, from_fields=['specific'], to_fields=['id'], related_name='+', ).contribute_to_class( M2MSpecific, 'specific_related_fk', virtual_only=True, ) class SignalTenantModel(TenantModel): class Meta: app_label = 'tests' class TenantMeta: related_name = 'signal_models' _logs = {}
template = '%(expressions)s' arg_joiner = ' - ' arity = 2 def __init__(self, start, end): super(DateDiff, self).__init__(start, end) def as_microsoft(self, compiler, connection): self.template = 'cast(DateDiff(day,%(expressions)s) as float)* -1 *24*60*60*1000.0*1000.0' # Convert to microseconds as used by Django DurationField' self.arg_joiner = ', ' return super(DateDiff, self).as_sql(compiler, connection) def as_sql(self, compiler, connection, function=None, template=None): if connection.vendor is 'microsoft': return self.as_microsoft(compiler, connection) return super(DateDiff, self).as_sql(compiler, connection) class NotEqual(Lookup): lookup_name = 'ne' def as_sql(self, qn, connection): lhs, lhs_params = self.process_lhs(qn, connection) rhs, rhs_params = self.process_rhs(qn, connection) params = lhs_params + rhs_params return '%s != %s' % (lhs, rhs), params Field.register_lookup(NotEqual) RelatedField.register_lookup(NotEqual) ForeignObject.register_lookup(NotEqual) ManyToManyField.register_lookup(NotEqual)
from django.db.models.fields.related import ForeignObject from django.db.models.fields.related_lookups import RelatedLookupMixin from lookup_extensions.lookups import Complement class RelatedComplement(RelatedLookupMixin, Complement): pass ForeignObject.register_lookup(RelatedComplement)
arity = 2 def __init__(self, start, end): super(DateDiff, self).__init__(start, end) def as_microsoft(self, compiler, connection): self.template = 'cast(DateDiff(day,%(expressions)s) as float)* -1 *24*60*60*1000.0*1000.0' # Convert to microseconds as used by Django DurationField' self.arg_joiner = ', ' return super(DateDiff, self).as_sql(compiler, connection) def as_sql(self, compiler, connection, function=None, template=None): if connection.vendor is 'microsoft': return self.as_microsoft(compiler, connection) return super(DateDiff, self).as_sql(compiler, connection) class NotEqual(Lookup): lookup_name = 'ne' def as_sql(self, qn, connection): lhs, lhs_params = self.process_lhs(qn, connection) rhs, rhs_params = self.process_rhs(qn, connection) params = lhs_params + rhs_params return '%s != %s' % (lhs, rhs), params Field.register_lookup(NotEqual) RelatedField.register_lookup(NotEqual) ForeignObject.register_lookup(NotEqual) ManyToManyField.register_lookup(NotEqual)
class MutableModelSubclass(MutableModel): non_mutable_fk = models.ForeignKey(SpecificModel, related_name='mutables') class Meta: app_label = 'tenancy' def test_mro(self): return 'MutableModelSubclass' class NonMutableModel(TenantModel): mutable_fk = models.ForeignKey(MutableModel, related_name='non_mutables') class Meta: app_label = 'tenancy' def test_mro(self): return 'NonMutableModel' try: from django.db.models.fields.related import ForeignObject except ImportError: pass else: ForeignObject(RelatedTenantModel, ['specific'], ['fk'], related_name='+').contribute_to_class(M2MSpecific, 'specific_related_fk', virtual_only=True)