Beispiel #1
0
    def _create_batch(self, batch_or_str, target_field_name=None):
        batch = batch_or_str
        if isinstance(batch_or_str, basestring):
            batch = Batch(batch_or_str)
        if target_field_name:
            batch.target_field_name = target_field_name

        _check_field_exists(self.model, batch.m2m_fieldname)
        return batch
Beispiel #2
0
    def _create_batch(self, batch_or_str, target_field_name=None):
        batch = batch_or_str
        if isinstance(batch_or_str, basestring):
            batch = Batch(batch_or_str)
        if target_field_name:
            batch.target_field_name = target_field_name

        _check_field_exists(self.model, batch.m2m_fieldname)
        return batch
Beispiel #3
0
 def test___check_field_exists_full_field_name(self):
     # make sure we can retrieve the "real" fieldname
     # given the full fieldname for a reverse foreign key
     # relationship
     # e.g. give "entry_set" we should get "entry"
     self.failUnlessEqual("entry",
                          _check_field_exists(Section, "entry_set"))
Beispiel #4
0
def _check_field_exists(model, fieldname):
    try:
        field_object, model, direct, m2m = model._meta.get_field_by_name(
            fieldname)
    except FieldDoesNotExist:
        # might be after reverse foreign key
        # which by default don't have the name we expect
        if fieldname.endswith('_set'):
            return _check_field_exists(model, fieldname[:-len('_set')])
        else:
            raise
    if not m2m:
        if direct:  # reverse foreign key relationship
            _not_exists(fieldname)
    return fieldname
Beispiel #5
0
 def test___check_field_exists_full_field_name_non_existant_field(self):
     try:
         _check_field_exists(Section, "qwerty_set")
         self.fail('selected field that does not exist')
     except FieldDoesNotExist:
         pass
Beispiel #6
0
 def test___check_field_exists_full_field_name(self):
     # make sure we can retrieve the "real" fieldname
     # given the full fieldname for a reverse foreign key
     # relationship
     # e.g. give "entry_set" we should get "entry"
     self.failUnlessEqual("entry", _check_field_exists(Section, "entry_set"))
Beispiel #7
0
 def test___check_field_exists_full_field_name_non_existant_field(self):
     try:
         _check_field_exists(Section, "qwerty_set")
         self.fail('selected field that does not exist')
     except FieldDoesNotExist:
         pass
Beispiel #8
0
def batch_select(model, instances, target_field_name, fieldname, filter=None):
    '''
    basically do an extra-query to select the many-to-many
    field values into the instances given. e.g. so we can get all
    Entries and their Tags in two queries rather than n+1
    
    returns a list of the instances with the newly attached fields
    
    batch_select(Entry, Entry.objects.all(), 'tags_all', 'tags')
    
    would return a list of Entry objects with 'tags_all' fields
    containing the tags for that Entry
    
    filter is a function that can be used alter the extra-query - it 
    takes a queryset and returns a filtered version of the queryset
    
    NB: this is a semi-private API at the moment, but may be useful if you
    dont want to change your model/manager.
    '''

    fieldname = _check_field_exists(model, fieldname)

    instances = list(instances)
    ids = [instance.pk for instance in instances]

    field_object, model, direct, m2m = model._meta.get_field_by_name(fieldname)
    if m2m:
        if not direct:
            m2m_field = field_object.field
            related_model = field_object.model
            related_name = m2m_field.name
            id_column = m2m_field.m2m_reverse_name()
            db_table = m2m_field.m2m_db_table()
        else:
            m2m_field = field_object
            related_model = m2m_field.rel.to  # model on other end of relationship
            related_name = m2m_field.related_query_name()
            id_column = m2m_field.m2m_column_name()
            db_table = m2m_field.m2m_db_table()
    elif not direct:
        # handle reverse foreign key relationships
        fk_field = field_object.field
        related_model = field_object.model
        related_name = fk_field.name
        id_column = fk_field.column
        db_table = related_model._meta.db_table

    related_instances = _select_related_instances(related_model, related_name,
                                                  ids, db_table, id_column)

    if filter:
        related_instances = filter(related_instances)

    grouped = {}
    id_attr = _id_attr(id_column)
    for related_instance in related_instances:
        instance_id = getattr(related_instance, id_attr)
        group = grouped.get(instance_id, [])
        group.append(related_instance)
        grouped[instance_id] = group

    for instance in instances:
        setattr(instance, target_field_name, grouped.get(instance.pk, []))

    return instances