Issue: Allow foreign key select fields to be set in Meta config
Author: prggmr
State: closed
Created: 2012-02-21 20:44:22

Basically as it says, 

I ran into the problem that unnecessary data tied to a model was being returned during the FK selection and since most of my FK lookups are parsed and directly outputted to an API performing an inline filter for these unwanted fields on a case by case basis would be cumbersome and error prone.

So I just hacked into peewee and put it in the Models Meta config to allow for this, I am not 100% if it needed to go both in the _ForeignRelatedObject_ & _ReverseForeignRelatedObject_ so I just stuck it in _ForeignRelatedObject_.

Below is an example

```
class User(Model):

    class Meta:
        db_table = 'user'
        fk_select = ['username', 'email', 'id']

    id = PrimaryKeyField(db_index = True)
    email = CharField(db_index = True, unique = True)
    password = CharField()
    username = CharField(unique = True, null = True)
    verified = BooleanField(null = True)
    verification_code = CharField(null = True)
```

Also note sure if this has gone into the latest already but I have reconstructed the "R" objects to work as "Q" objects in the sense you can join them using "&" and  "|" syntax which proved very helpful to me when writing some more complex queries, this is not in my fork but if you are interested just let me know.


See commit 7b76eca5b14211d70aa8231b2c1b65cb6a6e5b36 not sure how that other one got so messed up ... 


I will pass on merging this.  Traversing the FK lookup is a convenient shorthand, and not really painful if doing in small amounts.  If you're following this relationship in a loop, though, then you are costing yourself N+1 queries for the size of the result set.  This can be boiled down to a single quiery using the explicit select syntax:

```
# loop over all the blog entries
Entry.select({
    Entry: ['pk', 'title', 'blog'],
    Blog: ['id', 'title'],
    User: ['username'],
}).join(Blog).join(User)

# Yields the following SQL:
SELECT t1."pk", t1."title", t1."blog_id", t2."id", t2."title", t3."username" 
FROM "entry" AS t1 
INNER JOIN "blog" AS t2 
    ON t1."blog_id" = t2."id"
LEFT OUTER JOIN "users" AS t3
    ON t2."id" = t3."blog_id"
```

then, traversing lookups will not cost you an extra query and the related models will only be populated with the field syo uexplicitly selected.

As for the other thing, the R() objects, i'd definitley be interested in seeing a diff!


Defiantly makes sense in terms of loop performance but in my case models are only queried for a single result and returned giving the cost of +1 query outweighed by the benefit of a standardized select with less overall code.

As for the R object all I simply did was put together the following.

Note that this could probably be better as this was a quick fix but for my purposes of needing complex where expressions joined directly with a Q object has worked so far without problems.

```
class R(object):
    def __init__(self, *params):
        self.params = params
        self.parent = None

    def sql_select(self):
        if len(self.params) == 2:
            return self.params
        else:
            raise ValueError('Incorrect number of argument provided for R() expression')

    def connect(self, connector):
        if self.parent is None:
            self.parent = Node(connector)
            self.parent.children.append(self)

    def __or__(self, rhs):
        self.connect('OR')
        return self.parent | rhs

    def __and__(self, rhs):
        self.connect('AND')
        return self.parent & rhs

    def sql_where(self):
        return self.params[0], self.params[1:]
```

Disregard last found a possible solution.