Skip to content
New issue

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

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

Already on GitHub? Sign in 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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment