0

I made a template tag to show the current user if they have any unread notifications in the base template. I think that I need to pass in two arguments - one to establish that we are only showing notifications for the current user (using filter to do this), and the second to return if there are any unread notifications (also using filter for this). However, I am getting an error saying that I can only pass through one argument even though I need two.

Here if my template tag:

@register.simple_tag(name='notseen')
def notseen():
    if UserNotification.objects.filter(toUser=User) and UserNotification.objects.filter(read=False).exists():
        print("True")
        return True
    else:
        print("False")
        return False

Here is the Traceback:

Traceback (most recent call last):
  File "/anaconda3/envs/dev/lib/python3.6/site-packages/django/core/handlers/exception.py", line 41, in inner
    response = get_response(request)
  File "/anaconda3/envs/dev/lib/python3.6/site-packages/django/core/handlers/base.py", line 217, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/anaconda3/envs/dev/lib/python3.6/site-packages/django/core/handlers/base.py", line 215, in _get_response
    response = response.render()
  File "/anaconda3/envs/dev/lib/python3.6/site-packages/django/template/response.py", line 107, in render
    self.content = self.rendered_content
  File "/anaconda3/envs/dev/lib/python3.6/site-packages/django/template/response.py", line 84, in rendered_content
    content = template.render(context, self._request)
  File "/anaconda3/envs/dev/lib/python3.6/site-packages/django/template/backends/django.py", line 66, in render
    return self.template.render(context)
  File "/anaconda3/envs/dev/lib/python3.6/site-packages/django/template/base.py", line 207, in render
    return self._render(context)
  File "/anaconda3/envs/dev/lib/python3.6/site-packages/django/template/base.py", line 199, in _render
    return self.nodelist.render(context)
  File "/anaconda3/envs/dev/lib/python3.6/site-packages/django/template/base.py", line 990, in render
    bit = node.render_annotated(context)
  File "/anaconda3/envs/dev/lib/python3.6/site-packages/django/template/base.py", line 957, in render_annotated
    return self.render(context)
  File "/anaconda3/envs/dev/lib/python3.6/site-packages/django/template/loader_tags.py", line 177, in render
    return compiled_parent._render(context)
  File "/anaconda3/envs/dev/lib/python3.6/site-packages/django/template/base.py", line 199, in _render
    return self.nodelist.render(context)
  File "/anaconda3/envs/dev/lib/python3.6/site-packages/django/template/base.py", line 990, in render
    bit = node.render_annotated(context)
  File "/anaconda3/envs/dev/lib/python3.6/site-packages/django/template/base.py", line 957, in render_annotated
    return self.render(context)
  File "/anaconda3/envs/dev/lib/python3.6/site-packages/django/template/defaulttags.py", line 322, in render
    return nodelist.render(context)
  File "/anaconda3/envs/dev/lib/python3.6/site-packages/django/template/base.py", line 990, in render
    bit = node.render_annotated(context)
  File "/anaconda3/envs/dev/lib/python3.6/site-packages/django/template/base.py", line 957, in render_annotated
    return self.render(context)
  File "/anaconda3/envs/dev/lib/python3.6/site-packages/django/template/library.py", line 203, in render
    output = self.func(*resolved_args, **resolved_kwargs)
  File "/Users/garrettlove/Desktop/evverest/notify/templatetags/notify_extras.py", line 11, in notseen
    if UserNotification.objects.filter(toUser=User) and UserNotification.objects.filter(read=False).exists():
  File "/anaconda3/envs/dev/lib/python3.6/site-packages/django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/anaconda3/envs/dev/lib/python3.6/site-packages/django/db/models/query.py", line 784, in filter
    return self._filter_or_exclude(False, *args, **kwargs)
  File "/anaconda3/envs/dev/lib/python3.6/site-packages/django/db/models/query.py", line 802, in _filter_or_exclude
    clone.query.add_q(Q(*args, **kwargs))
  File "/anaconda3/envs/dev/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1250, in add_q
    clause, _ = self._add_q(q_object, self.used_aliases)
  File "/anaconda3/envs/dev/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1276, in _add_q
    allow_joins=allow_joins, split_subq=split_subq,
  File "/anaconda3/envs/dev/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1210, in build_filter
    condition = self.build_lookup(lookups, col, value)
  File "/anaconda3/envs/dev/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1104, in build_lookup
    return final_lookup(lhs, rhs)
  File "/anaconda3/envs/dev/lib/python3.6/site-packages/django/db/models/lookups.py", line 24, in __init__
    self.rhs = self.get_prep_lookup()
  File "/anaconda3/envs/dev/lib/python3.6/site-packages/django/db/models/lookups.py", line 72, in get_prep_lookup
    return self.rhs._prepare(self.lhs.output_field)
TypeError: _prepare() takes 1 positional argument but 2 were given

Edit: I added print(myUser.__dict__) to the if statement and this is the output

{'__module__': 'django.contrib.auth.models', '__doc__': '\n    Users within the Django authentication system are represented by this\n    model.\n\n    Username, password and email are required. Other fields are optional.\n    ', '_meta': <Options for User>, 'DoesNotExist': <class 'django.contrib.auth.models.DoesNotExist'>, 'MultipleObjectsReturned': <class 'django.contrib.auth.models.MultipleObjectsReturned'>, 'get_next_by_date_joined': <function curry.<locals>._curried at 0x1024c3598>, 'get_previous_by_date_joined': <function curry.<locals>._curried at 0x1024c3620>, 'groups': <django.db.models.fields.related_descriptors.ManyToManyDescriptor object at 0x1024c7f98>, 'user_permissions': <django.db.models.fields.related_descriptors.ManyToManyDescriptor object at 0x1024d0630>, 'id': <django.db.models.query_utils.DeferredAttribute object at 0x1024d0748>, 'logentry_set': <django.db.models.fields.related_descriptors.ReverseManyToOneDescriptor object at 0x1024d0828>, 'userprofile': <django.db.models.fields.related_descriptors.ReverseOneToOneDescriptor object at 0x1024ee358>, 'userpost': <django.db.models.fields.related_descriptors.ReverseManyToOneDescriptor object at 0x1024f65c0>, 'post_likes': <django.db.models.fields.related_descriptors.ManyToManyDescriptor object at 0x1024f6630>, 'usercomment': <django.db.models.fields.related_descriptors.ReverseManyToOneDescriptor object at 0x1024eeeb8>, 'blogpost': <django.db.models.fields.related_descriptors.ReverseManyToOneDescriptor object at 0x1025065c0>, 'blogcomment': <django.db.models.fields.related_descriptors.ReverseManyToOneDescriptor object at 0x102506c50>, 'user': <django.db.models.fields.related_descriptors.ReverseManyToOneDescriptor object at 0x10250e6a0>, 'emailaddress_set': <django.db.models.fields.related_descriptors.ReverseManyToOneDescriptor object at 0x102548240>, 'socialaccount_set': <django.db.models.fields.related_descriptors.ReverseManyToOneDescriptor object at 0x10256a128>}
Garrett
  • 1,576
  • 4
  • 27
  • 51
  • `filter(toUser=User)` - unless you've got a variable with the same name as the class i doubt this works as you expect – Sayse Nov 14 '17 at 19:22
  • @Sayse I have this line right above it: `User = get_user_model()` – Garrett Nov 14 '17 at 19:23
  • humm .. above what ? it should be above if statement – Vaibhav Nov 14 '17 at 19:39
  • The `@register` line – Garrett Nov 14 '17 at 19:40
  • it doesnt work that way , Check python variable scope https://stackoverflow.com/questions/291978/short-description-of-the-scoping-rules – Vaibhav Nov 14 '17 at 19:41
  • Put User before if statement and after register – Vaibhav Nov 14 '17 at 19:42
  • @Vaibhav did that but still had error. I changed the first filter in the if statement to be this `UserNotification.objects.filter(toUser=User.username)` and all errors go away but it doesn't work in the base template the way it should – Garrett Nov 14 '17 at 19:45

1 Answers1

1

Check Python Scope here

@register.simple_tag(name='notseen')
def notseen():
    # Add User varaible here
    myUser = get_user_model()
    if UserNotification.objects.filter(toUser=myUser) and UserNotification.objects.filter(read=False).exists():
        print("True")
        return True
    else:
        print("False")
        return False
Vaibhav
  • 1,154
  • 10
  • 26
  • did that but still had error. I changed the first filter in the if statement to be this `UserNotification.objects.filter(toUser=User.username)` and all errors go away but it doesn't work in the base template the way it should – Garrett Nov 14 '17 at 19:45
  • 1) Change User to myUser (some other as its a keyword and cant be an variable name) i.e User = get_user_model() --> myUser = get_user_model(), 2) Check what you have in myUser with print(myUser.__dict__) , check if username is available inside myUser – Vaibhav Nov 14 '17 at 19:50
  • I posted an edit in the post to show the output of that print statement – Garrett Nov 14 '17 at 19:55
  • change this UserNotification.objects.filter(toUser=User.username) to UserNotification.objects.filter(toUser=myUser) – Vaibhav Nov 14 '17 at 19:58
  • brings me back to the error I had before: `TypeError at / _prepare() takes 1 positional argument but 2 were given` – Garrett Nov 14 '17 at 20:01
  • check with UserNotification.objects.filter(toUser=myUser.user) – Vaibhav Nov 14 '17 at 20:01
  • Error is gone but template tag doesn't work properly – Garrett Nov 14 '17 at 20:04
  • you are returning True and False, whats going to template ? – Vaibhav Nov 14 '17 at 20:06
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/159000/discussion-between-garrett-and-vaibhav). – Garrett Nov 14 '17 at 20:08