Issue: local variable 'model_attr' referenced before assignment
Author: marcpearson
State: closed
Created: 2022-06-13 23:54:07

Hi

I updated my project to version 3.14.10 and receive this error. The error come from the convert_dict_to_node function. From my observation, i think the code is missing the assignation to model_attr in the for piece in key.split('__'):

`def convert_dict_to_node(self, qdict):
        accum = []
        joins = []
        fks = (ForeignKeyField, BackrefAccessor)
        for key, value in sorted(qdict.items()):
            curr = self.model
            if '__' in key and key.rsplit('__', 1)[1] in DJANGO_MAP:
                key, op = key.rsplit('__', 1)
                op = DJANGO_MAP[op]
            elif value is None:
                op = DJANGO_MAP['is']
            else:
                op = DJANGO_MAP['eq']

            if '__' not in key:
                # Handle simplest case. This avoids joining over-eagerly when a
                # direct FK lookup is all that is required.
                model_attr = getattr(curr, key)
            else:
                for piece in key.split('__'):
                    model_attr = getattr(curr, piece) <==============================   Maybe this line is needed
                    for dest, attr, _, _ in self._joins.get(curr, ()):
                        if attr == piece or (isinstance(dest, ModelAlias) and
                                             dest.alias == piece):
                            curr = dest
                            break
                    else:
                        model_attr = getattr(curr, piece)
                        if value is not None and isinstance(model_attr, fks):
                            curr = model_attr.rel_model
                            joins.append(model_attr)
            accum.append(op(model_attr, value))
        return accum, joins`

With this new line my code work as before with the version 2.10.2

Thanks in advance

I can't replicate the exception -- I agree that it looks like there may be a bug there, but I'm not sure how to trigger it. The following all work just fine:

```python
class TestDjangoFilterRegression(ModelTestCase):
    requires = [User, Tweet]

    def test_django_filter_regression(self):
        a, b, c = [User.create(username=u) for u in 'abc']
        Tweet.create(user=a, content='a1')
        Tweet.create(user=a, content='a2')
        Tweet.create(user=b, content='b1')

        query = User.filter(username='a')
        self.assertEqual(sorted([u.username for u in query]), ['a'])

        query = User.filter(username__in=('a', 'c', 'x'))
        self.assertEqual(sorted([u.username for u in query]), ['a', 'c'])

        query = Tweet.filter(user__username='a')
        self.assertEqual(sorted([t.content for t in query]), ['a1', 'a2'])

        query = Tweet.filter(user__username__in=('a', 'c'))
        self.assertEqual(sorted([t.content for t in query]), ['a1', 'a2'])
```

I think you need to have 3 level relations like this

```
class Hour(Model):
    project = ForeignKeyField(Project, backref="hours")

class Project(Model):
    client = ForeignKeyField(Client, backref="projects")

class Client(Model):
```

When i want to filter all the hours (of all projects) for a specific client, i can filter the hours with a Django criteria 'project__client=1' in previous version without error. The criteria is coming from the URL for a backend call

I hope this will help you

 N.B I do my best to write in english, i'm a french speaker. Sorry if is not sound good ! 






I'm still unable to replicate the issue: https://github.com/coleifer/peewee/blob/master/tests/regressions.py#L1705-L1710 -- this is traversing 2 relationships. That unit test covers quite a few scenarios.

If you can produce a failing test in the above case, or write a new one that demonstrates the issue, I will gladly reopen.

Could you give me some advise how to set the project to run tests. I'll take a look and try to reproduce the error. Thanks !

A git checkout and executing «runtest.py regressions» seem to do the job. I will print a comment in every step to check if your regressions tests invoke every possible situation of convert_dict_to_node. Does it seem a good idea ?

Presumably if you are able to replicate the exception locally with your own code, you can communicate to me what is different about it vs the tests, or how to modify the tests to replicate it...

Finally figured it out, will post a fix shortly.

Glad you found it ! You're right on. My query is using already joined relations too. Thanks for your help and the incoming release