def display_merge_animal_length_row(destination, source, merge_form, form_field_name, length_field_name, sigdigs_field_name):
    
    destination_value = [None, None]
    source_value = [None, None]
    in_source = [False, False]
    differ = False
    destination_cell = [None, None]
    source_cell = [None, None]
    # the source may not have all the fields of the destination
    for i, f in enumerate((length_field_name, sigdigs_field_name)):
        destination_value[i] = getattr(destination, f)
        try:
            source_value[i] = getattr(source, f)
            in_source[i] = True
        except AttributeError:
            pass
    
        if in_source[i]:
            differ |= not bool(destination_value[i] == source_value[i])
    
    destination_cell[0] = display_animal_length_cell(destination, length_field_name, destination_value[1])
    if in_source[0]:
        source_cell[0] = display_animal_length_cell(source, length_field_name, source_value[1])
    else:
        source_cell[0] = mark_safe(u'<td class="added"><i>no field</i></td>')

    destination_cell[1] = display_cell(destination, f)
    if in_source[1]:
        source_cell[1] = display_cell(source, f)
    else:
        source_cell[1] = mark_safe(u'<td class="added"><i>no field</i></td>')
    
    return render_to_string(
        'display_animal_length_merge_row.html',
        {
            'differ': differ,
            'in_source': in_source,
            'destination_cell': destination_cell,
            'source_cell': source_cell,
            'field': merge_form[form_field_name],
        },
    )
def display_merge_row(destination, source, merge_form, field_name, cell_template_name=None, cell_kwargs={}, template='display_merge_row.html'):
    if isinstance(destination._meta.get_field(field_name), models.ManyToManyField):
        # comparing m2m fields is a little more complicated
        # unsaved instances may not have PKs yet
        if not destination.pk:
            destination_value = tuple()
        else:
            destination_value = getattr(destination, field_name)
    else:
        destination_value = getattr(destination, field_name)
    
    # the source may not have all the fields of the destination
    try:
        if isinstance(source._meta.get_field(field_name), models.ManyToManyField):
            # comparing m2m fields is a little more complicated
            # unsaved instances may not have PKs yet
            if not source.pk:
                source_value = tuple()
            else:
                source_value = getattr(source, field_name)
        else:
            source_value = getattr(source, field_name)
        in_source = True
    except models.fields.FieldDoesNotExist:
        in_source = False
    
    if in_source:
        if isinstance(destination_value, models.Manager):
            def _pks_set(manager):
                return set(manager.values_list('pk', flat=True))
            if isinstance(source_value, models.Manager):
                differ = not bool(_pks_set(destination_value) == _pks_set(source_value))
            else:
                differ = not bool(_pks_set(destination_value) == set(source_value))
        else:
            differ = not bool(destination_value == source_value)
    else:
        differ = None
    
    if isinstance(cell_kwargs, tuple):
        destination_kwargs, source_kwargs = cell_kwargs
    else:
        destination_kwargs, source_kwargs = map(copy, (cell_kwargs, cell_kwargs))

    destination_cell = display_cell(destination, field_name, cell_template_name, **destination_kwargs)

    if in_source:
        source_cell = display_cell(source, field_name, cell_template_name, **source_kwargs)
    else:
        source_cell = mark_safe(u'<td class="added"><i>no field</i></td>')
    
    return render_to_string(
        template,
        {
            'differ': differ,
            'in_source': in_source,
            'destination_cell': destination_cell,
            'source_cell': source_cell,
            'field': merge_form[field_name],
        },
    )