ryanwaite28
ryanwaite28

Reputation: 2038

Python Django - Models: for loop in query/filter

so i want to do a query where a field equals a property of an object in a for loop. Here is a working sample/example using sqlAlchemy:

you =   session.query(Users).filter_by(id=login_session['userid']).first()

friends = session.query(Friends).filter_by(user_id=you.id).all()

dashboard = session.query(Markers).filter(Markers.owner.in_([f.friend_id for f in friends)]).all()

How would i do this in django?

Here is what i tried:

you = Accounts.objects.get(uname = request.session['username'])

following = Follows.objects.filter(userid=you.id)

POSTS = Posts.objects.filter(ownerid = [f.follow_id for f in following])

and this is what i got:

Traceback:

File "C:\Users\waite-ryan-m\Desktop\WPython\WinPython-64bit-2.7.12.1Zero\python-2.7.12.amd64\lib\site-packages\django\core\handlers\base.py" in get_response
  149.                     response = self.process_exception_by_middleware(e, request)

File "C:\Users\waite-ryan-m\Desktop\WPython\WinPython-64bit-2.7.12.1Zero\python-2.7.12.amd64\lib\site-packages\django\core\handlers\base.py" in get_response
  147.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "C:\Users\waite-ryan-m\Desktop\WPython\WinPython-64bit-2.7.12.1Zero\python-2.7.12.amd64\lib\site-packages\django\utils\decorators.py" in _wrapped_view
  149.                     response = view_func(request, *args, **kwargs)

File "C:\Users\waite-ryan-m\Desktop\epsity\webapp\views.py" in profileMain
  102.             POSTS = Posts.objects.filter(ownerid = [f.follow_id for f in following])

File "C:\Users\waite-ryan-m\Desktop\WPython\WinPython-64bit-2.7.12.1Zero\python-2.7.12.amd64\lib\site-packages\django\db\models\manager.py" in manager_method
  122.                 return getattr(self.get_queryset(), name)(*args, **kwargs)

File "C:\Users\waite-ryan-m\Desktop\WPython\WinPython-64bit-2.7.12.1Zero\python-2.7.12.amd64\lib\site-packages\django\db\models\query.py" in filter
  790.         return self._filter_or_exclude(False, *args, **kwargs)

File "C:\Users\waite-ryan-m\Desktop\WPython\WinPython-64bit-2.7.12.1Zero\python-2.7.12.amd64\lib\site-packages\django\db\models\query.py" in _filter_or_exclude
  808.             clone.query.add_q(Q(*args, **kwargs))

File "C:\Users\waite-ryan-m\Desktop\WPython\WinPython-64bit-2.7.12.1Zero\python-2.7.12.amd64\lib\site-packages\django\db\models\sql\query.py" in add_q
  1243.         clause, _ = self._add_q(q_object, self.used_aliases)

File "C:\Users\waite-ryan-m\Desktop\WPython\WinPython-64bit-2.7.12.1Zero\python-2.7.12.amd64\lib\site-packages\django\db\models\sql\query.py" in _add_q
  1269.                     allow_joins=allow_joins, split_subq=split_subq,

File "C:\Users\waite-ryan-m\Desktop\WPython\WinPython-64bit-2.7.12.1Zero\python-2.7.12.amd64\lib\site-packages\django\db\models\sql\query.py" in build_filter
  1203.             condition = self.build_lookup(lookups, col, value)

File "C:\Users\waite-ryan-m\Desktop\WPython\WinPython-64bit-2.7.12.1Zero\python-2.7.12.amd64\lib\site-packages\django\db\models\sql\query.py" in build_lookup
  1099.                 return final_lookup(lhs, rhs)

File "C:\Users\waite-ryan-m\Desktop\WPython\WinPython-64bit-2.7.12.1Zero\python-2.7.12.amd64\lib\site-packages\django\db\models\lookups.py" in __init__
  19.         self.rhs = self.get_prep_lookup()

File "C:\Users\waite-ryan-m\Desktop\WPython\WinPython-64bit-2.7.12.1Zero\python-2.7.12.amd64\lib\site-packages\django\db\models\lookups.py" in get_prep_lookup
  57.         return self.lhs.output_field.get_prep_lookup(self.lookup_name, self.rhs)

File "C:\Users\waite-ryan-m\Desktop\WPython\WinPython-64bit-2.7.12.1Zero\python-2.7.12.amd64\lib\site-packages\django\db\models\fields\__init__.py" in get_prep_lookup
  1860.         return super(IntegerField, self).get_prep_lookup(lookup_type, value)

File "C:\Users\waite-ryan-m\Desktop\WPython\WinPython-64bit-2.7.12.1Zero\python-2.7.12.amd64\lib\site-packages\django\db\models\fields\__init__.py" in get_prep_lookup
  744.             return self.get_prep_value(value)

File "C:\Users\waite-ryan-m\Desktop\WPython\WinPython-64bit-2.7.12.1Zero\python-2.7.12.amd64\lib\site-packages\django\db\models\fields\__init__.py" in get_prep_value
  1854.         return int(value)

Exception Type: TypeError at /main/
Exception Value: int() argument must be a string or a number, not 'list'

My models:

class Accounts(models.Model):

    uname = models.CharField(max_length = 20, default = '')
    displayname = models.CharField(max_length = 30, default = '')
    email = models.CharField(max_length = 50, default = '')
    pswrd = models.CharField(max_length = 50, default = '')
    provider = models.CharField(max_length = 20, default = '')
    provider_id = models.CharField(max_length = 100, default = '')
    avi = models.CharField(max_length = 500, default = '/static/img/anon2.png')
    background = models.CharField(max_length = 500, default = '/static/img/bg-default.jpg')
    gender = models.CharField(max_length = 25, default = '')
    phone = models.CharField(max_length = 25, default = '')

    type = models.CharField(max_length = 20, default = '')
    status = models.CharField(max_length = 9, default = 'public')
    # status: either public, private or deleted

    official = models.IntegerField(default = 0)
    # official: 1 = True | 0 = False

    interests = models.CharField(max_length = 1725, default = '')
    seeking = models.CharField(max_length = 1725, default = '')

    bio_desc = models.CharField(max_length = 150, default = '')
    bio_link = models.CharField(max_length = 150, default = '')
    #bio_link_name = models.CharField(max_length = 100, default = '')

    date_created = models.DateField( default = datetime.datetime.now )
    last_active = models.DateField(auto_now=True)

    @property
    def serialize(self):
         # Returns Data Object In Proper Format
        return {
            'userid': self.id,
            'uname': self.uname,
            'displayname': self.displayname,
            'avi': self.avi,
            'status': self.status,
            'background': self.background,
        }

    @property
    def get_bio(self):
         # Returns Data Object In Proper Format
        return {
            'desc': self.bio_desc,
            'link': self.bio_link,
            #'linkName': self.bio_link_name,
        }

    @property
    def get_info(self):
         # Returns Data Object In Proper Format
        return {
            'interests': self.interests,
            'seeking': self.seeking,
            #'linkName': self.bio_link_name,
        }

    class Meta:
        db_table = "accounts"

# --- #

class Follows(models.Model):

    userid = models.IntegerField(blank = False, default = 0)
    user_rel = models.ForeignKey(Accounts, default = 0, related_name = "user_rel")

    follow_id = models.IntegerField(blank = False, default = 0)
    follow_rel = models.ForeignKey(Accounts, default = 0, related_name = "follow_rel")

    date_created = models.DateField( default = datetime.datetime.now )

    @property
    def serialize(self):
         # Returns Data Object In Proper Format
        return {
            'fid': self.id,

            'userid': self.userid,
            'user': self.user_rel.serialize,
            'followid': self.follow_id,
            'follow': self.follow_rel.serialize,
            'date_created': self.date_created
            #'linkName': self.bio_link_name,
        }

    class Meta:
        db_table = "follows"

# ---

class Posts(models.Model):

    OwnerType = (
        ('Account', 'Account'),
        ('Group', 'Group'),
    )

    PostTypes = (
        ('Text', 'Text'),
        ('Photo', 'Photo'),
        ('Audio', 'Audio'),
        ('Video', 'Video'),
    )

    ownerid = models.IntegerField(blank = False, default = 0)
    owner_type = models.CharField(choices = OwnerType, blank = False, default = '', max_length = 50)

    title = models.CharField(max_length = 500, default = '')
    contents = models.CharField(max_length = 500, default = '')
    link = models.CharField(max_length = 500, default = '')

    attachment = models.CharField(max_length = 500, default = '')
    attachment_type = models.CharField(max_length = 500, default = '')

    post_type = models.CharField(max_length = 20, choices = PostTypes, default = '')
    status = models.CharField(max_length = 20, default = 'public') # either public, private, or deleted

    date_created = models.DateField( default = datetime.datetime.now )
    last_active = models.DateField(auto_now=True)

    @property
    def serialize(self):
        return {
            'p_id': self.id,

            'ownerid': self.ownerid,
            'owner': returnModelSerialized( self.owner_type , self.ownerid ),
            'owner_type': self.owner_type,
            'title': self.title,
            'contents': self.contents,
            'attachment': self.attachment,
            'attachment_type': self.attachment_type,
            'link': self.link,
            'post_type': self.post_type,
            'status': self.status,
            'date_created': self.date_created,
            'last_active': self.last_active
        }

    class Meta:
        db_table = "posts"

# ---

Upvotes: 2

Views: 7820

Answers (2)

Chaitanya Patel
Chaitanya Patel

Reputation: 460

Alasdair's answer is correct. You should not pass a list while comparing an attribute. I want to add an improvement.

  • While you are using Foreign key, you don't need user_id type field separately. You can access it through foreign key also. Django Foreign Key is very useful in applications like you are using. Here is documentation which contains similar example as yours. Go through it. Hope that might help.

Upvotes: 2

Alasdair
Alasdair

Reputation: 308779

You are getting the error because your filter expects the id of a single instance, not a list of ids.

You can use __in to filter ids in a list:

POSTS = Posts.objects.filter(ownerid__in=[f.follow_id for f in following])

Upvotes: 9

Related Questions