Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

RelatedLinkColumn uses verbose_name instead of name #347

Closed
audricschiltknecht opened this issue Jun 30, 2016 · 3 comments · Fixed by #350, mozilla/addons-server#4430 or drummonds/bene#50 · May be fixed by pilnujemy/pytamy#67
Closed

Comments

@audricschiltknecht
Copy link
Contributor

Current code seems to be using the verbose_name of a field instead of its name. This breaks RelatedLinkColumn for field where the verbose_name is different from the field name.

For example, it's possible to break the tests by using the following diff:

diff --git a/tests/app/models.py b/tests/app/models.py
index 0a4415b..48f4ad0 100644
--- a/tests/app/models.py
+++ b/tests/app/models.py
@@ -18,7 +18,7 @@ class Person(models.Model):

     occupation = models.ForeignKey(
         'Occupation', related_name='people',
-        null=True, verbose_name='occupation')
+        null=True, verbose_name='occupation of the person')

     trans_test = models.CharField(
         max_length=200, blank=True,
@audricschiltknecht
Copy link
Contributor Author

Failure result:

========================================================================================================================================================== FAILURES ==========================================================================================================================================================
___________________________________________________________________________________________________________________________________________________ test_RelatedLinkColumn ___________________________________________________________________________________________________________________________________________________

    @pytest.mark.django_db
    def test_RelatedLinkColumn():
        carpenter = Occupation.objects.create(name='Carpenter')
        Person.objects.create(first_name='Bob', last_name='Builder', occupation=carpenter)

        class Table(tables.Table):
            first_name = tables.LinkColumn()
            last_name = tables.Column()
            occupation = tables.RelatedLinkColumn()

        table = Table(Person.objects.all())

>       assert table.rows[0].get_cell('occupation') == '<a href="/occupations/%d/">Carpenter</a>' % carpenter.pk

tests/columns/test_linkcolumn.py:188: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
django_tables2/rows.py:145: in get_cell
    return self._call_render(bound_column, value)
django_tables2/rows.py:156: in _call_render
    'table': self._table,
django_tables2/utils.py:501: in call_with_appropriate
    return fn(**kwargs)
django_tables2/columns/linkcolumn.py:164: in render
    self.compose_url(record, bound_column),
django_tables2/columns/linkcolumn.py:180: in compose_url
    return accessor.resolve(record).get_absolute_url()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = 'occupation of the person', context = <Person: Bob>, safe = True, quiet = False

    def resolve(self, context, safe=True, quiet=False):
        '''
            Return an object described by the accessor by traversing the attributes
            of *context*.

            Lookups are attempted in the following order:

             - dictionary (e.g. ``obj[related]``)
             - attribute (e.g. ``obj.related``)
             - list-index lookup (e.g. ``obj[int(related)]``)

            Callable objects are called, and their result is used, before
            proceeding with the resolving.

            Example::

                >>> x = Accessor('__len__')
                >>> x.resolve('brad')
                4
                >>> x = Accessor('0.upper')
                >>> x.resolve('brad')
                'B'

            Arguments:
                context (object): The root/first object to traverse.
                safe (bool): Don't call anything with `alters_data = True`
                quiet (bool): Smother all exceptions and instead return `None`

            Returns:
                target object

            Raises:
                TypeError`, `AttributeError`, `KeyError`, `ValueError`
                (unless `quiet` == `True`)
            '''
        try:
            current = context
            for bit in self.bits:
                try:  # dictionary lookup
                    current = current[bit]
                except (TypeError, AttributeError, KeyError):
                    try:  # attribute lookup
                        current = getattr(current, bit)
                    except (TypeError, AttributeError):
                        try:  # list-index lookup
                            current = current[int(bit)]
                        except (IndexError,  # list index out of range
                                ValueError,  # invalid literal for int()
                                KeyError,    # dict without `int(bit)` key
                                TypeError,   # unsubscriptable object
                                ):
                            raise ValueError('Failed lookup for key [%s] in %r'
>                                            ', when resolving the accessor %s' % (bit, current, self)
                                             )
E                                            ValueError: Failed lookup for key [occupation of the person] in <Person: Bob>, when resolving the accessor occupation of the person

django_tables2/utils.py:326: ValueError

@jieter
Copy link
Owner

jieter commented Jul 1, 2016

Interesting, thanks for reporting. Are you able/willing to open a Pull Request containing the test and a fix for it?

@audricschiltknecht
Copy link
Contributor Author

@jieter sure, I'll give it a try!

# for free to join this conversation on GitHub. Already have an account? # to comment