扩展用户模型:使用user.is_authenticated()时出现SimpleLazyObject错误

时间:2017-06-09 13:12:52

标签: python django django-models django-views

首先,我已经扩展了默认的Django用户以包含用户头像。我现在开始思考,如果我已经尽我所能做到这一点,因为尽管user_avatar字段现在可以参考 - 我在各个点都收到了一些问题。

models.py:

class UserProfile(models.Model):
    user = models.OneToOneField(User, related_name='userprofile')
    user_avatar = models.ImageField(storage=site_media_upload_location, null=True, blank=True)

class Post(models.Model):

    STATUS_CHOICES = (
        ('draft', 'Draft'),
        ('published', 'Published'),
    )

    POST_TYPES = (
        ('news', 'News'),
        ('feature', 'Feature'),
        ('review', 'Review'),
    )

    title = models.CharField(max_length=250)
    slug = models.SlugField(max_length=250, unique_for_date='publish')

    author = models.ForeignKey(UserProfile, related_name='blog_posts')

    body = models.TextField()
    lead_in = models.CharField(max_length=500, default='')

    #These next items shall contain our development information for game reviews - this is much like the lead_in:
    platform = models.CharField(max_length=1000, default='')
    publisher = models.CharField(max_length=1000, default='')
    developer = models.CharField(max_length=1000, default='')
    release = models.DateTimeField(default=timezone.now)
    is_featured = models.BooleanField(default=False)
    likes = models.ManyToManyField(UserProfile, blank=True, related_name='post_likes')

    #Out blog layout dictates each featurette has up to three scrolling images associated to it:
    image_scroll_1 = models.ImageField(storage=site_media_upload_location, null=True, blank=True)
    image_scroll_2 = models.ImageField(storage=site_media_upload_location, null=True, blank=True)
    image_scroll_3 = models.ImageField(storage=site_media_upload_location, null=True, blank=True)

    type = models.CharField(max_length=10,choices=POST_TYPES,default='review')

    publish = models.DateTimeField(default=timezone.now)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)
    status = models.CharField(max_length=10,choices=STATUS_CHOICES,default='draft')
    rating = models.PositiveSmallIntegerField(default=10)

    wrap_header = models.CharField(max_length=250, default='')
    wrap_up = models.TextField(default='')
    disclaimer = models.TextField(default='')

    objects = models.Manager()
    published = PublishedManager()
    tags = TaggableManager()

    class Meta:
        ordering = ('-publish',)

    def __str__(self):
        """Return the state title of the post"""
        return self.title

    def get_absolute_url(self):
        """Get absolute_url path specific to this post."""
        return reverse('blog:post_detail', args = [self.publish.year, self.publish.strftime('%m'), self.publish.strftime('%d'), self.slug])

    def get_like_api_toggle_url(self):
        return reverse('blog:like_api_toggle', args = [self.publish.year, self.publish.strftime('%m'), self.publish.strftime('%d'), self.slug])

    def get_image(self):
        """Get upload_to path specific to this photo."""
        return self.image.url

views.py:

class PostLikeAPIToggle(APIView):
    authentication_classes = (authentication.SessionAuthentication,)
    permission_classes = (permissions.IsAuthenticated,)

    def get(self, request, post=None, year=None, month=None, day=None, format=None):
        post = self.kwargs.get("post")
        obj = get_object_or_404(Post, slug=post)
        url_ = obj.get_absolute_url()
        user = self.request.user
        updated = False
        liked = False

        if request.user.is_authenticated():
            if user in obj.likes.all():
                liked = False
                obj.likes.remove(user)
            else:
                liked = True
                obj.likes.add(user)
            updated = True

        data = { 'updated': updated, 'liked': liked }
        return Response(data)

检查此用户是否已通过身份验证(request.user.is_authenticated())时,我收到以下错误:

'UserProfile' instance expected, got <SimpleLazyObject: <User: default_user>>

我尝试了很多事情,例如:

user = self.request.userprofile.user

user = self.request.user.userprofile

还有:

if user.userprofile.is_authenticated():

但无济于事。我想知道是否有人可以快速提供一些有关如何解决此问题的专业提示......

完整追溯:

回溯:

File "/Users/MichaelJRoberts/anaconda/envs/snakes/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner
  41.             response = get_response(request)

File "/Users/MichaelJRoberts/anaconda/envs/snakes/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  187.                 response = self.process_exception_by_middleware(e, request)

File "/Users/MichaelJRoberts/anaconda/envs/snakes/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  185.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/Users/MichaelJRoberts/anaconda/envs/snakes/lib/python3.6/site-packages/django/views/decorators/csrf.py" in wrapped_view
  58.         return view_func(*args, **kwargs)

File "/Users/MichaelJRoberts/anaconda/envs/snakes/lib/python3.6/site-packages/django/views/generic/base.py" in view
  68.             return self.dispatch(request, *args, **kwargs)

File "/Users/MichaelJRoberts/anaconda/envs/snakes/lib/python3.6/site-packages/rest_framework/views.py" in dispatch
  489.             response = self.handle_exception(exc)

File "/Users/MichaelJRoberts/anaconda/envs/snakes/lib/python3.6/site-packages/rest_framework/views.py" in handle_exception
  449.             self.raise_uncaught_exception(exc)

File "/Users/MichaelJRoberts/anaconda/envs/snakes/lib/python3.6/site-packages/rest_framework/views.py" in dispatch
  486.             response = handler(request, *args, **kwargs)

File "/Developer/Django/eos/blog/views.py" in get
  28.                 obj.likes.remove(user)

File "/Users/MichaelJRoberts/anaconda/envs/snakes/lib/python3.6/site-packages/django/db/models/fields/related_descriptors.py" in remove
  949.             self._remove_items(self.source_field_name, self.target_field_name, *objs)

File "/Users/MichaelJRoberts/anaconda/envs/snakes/lib/python3.6/site-packages/django/db/models/fields/related_descriptors.py" in _remove_items
  1145.                 self.through._default_manager.using(db).filter(filters).delete()

File "/Users/MichaelJRoberts/anaconda/envs/snakes/lib/python3.6/site-packages/django/db/models/query.py" in filter
  782.         return self._filter_or_exclude(False, *args, **kwargs)

File "/Users/MichaelJRoberts/anaconda/envs/snakes/lib/python3.6/site-packages/django/db/models/query.py" in _filter_or_exclude
  800.             clone.query.add_q(Q(*args, **kwargs))

File "/Users/MichaelJRoberts/anaconda/envs/snakes/lib/python3.6/site-packages/django/db/models/sql/query.py" in add_q
  1261.         clause, _ = self._add_q(q_object, self.used_aliases)

File "/Users/MichaelJRoberts/anaconda/envs/snakes/lib/python3.6/site-packages/django/db/models/sql/query.py" in _add_q
  1281.                     current_negated, allow_joins, split_subq)

File "/Users/MichaelJRoberts/anaconda/envs/snakes/lib/python3.6/site-packages/django/db/models/sql/query.py" in _add_q
  1287.                     allow_joins=allow_joins, split_subq=split_subq,

File "/Users/MichaelJRoberts/anaconda/envs/snakes/lib/python3.6/site-packages/django/db/models/sql/query.py" in build_filter
  1190.             self.check_related_objects(field, value, opts)

File "/Users/MichaelJRoberts/anaconda/envs/snakes/lib/python3.6/site-packages/django/db/models/sql/query.py" in check_related_objects
  1090.                     self.check_query_object_type(v, opts, field)

File "/Users/MichaelJRoberts/anaconda/envs/snakes/lib/python3.6/site-packages/django/db/models/sql/query.py" in check_query_object_type
  1065.                     (value, opts.object_name))

Exception Type: ValueError at /blog/api/2013/08/28/final-fantasy-xiv-realm-reborn/like/
Exception Value: Cannot query "michaeljroberts": Must be "UserProfile" instance.

1 个答案:

答案 0 :(得分:0)

这看起来不错:

if request.user.is_authenticated():

回溯显示错误在此行

obj.likes.remove(user)

您的多对多字段是UserProfile模型,而不是User模型。

likes = models.ManyToManyField(UserProfile, ...)

因此,在检查/添加/删除喜欢时,您应该使用该配置文件。

profile = user.userprofile
if profile in obj.likes.all():
    liked = False
    obj.likes.remove(profile)
else:
    liked = True
    obj.likes.add(profile)
updated = True