简体   繁体   English

'method'和'method'的实例之间不支持'<'-Python,Django

[英]'<' not supported between instances of 'method' and 'method' - Python, Django

I'm trying to do Winerama Recommender Tutorial . 我正在尝试做Winerama推荐教程 I met a error which I can't solve. 我遇到了我无法解决的错误。 When I try to go to the tab 'recommendation list' the browser returned the following error. 当我尝试转到“推荐列表”标签时,浏览器返回以下错误。

Error 错误

Environment:


Request Method: GET
Request URL: http://127.0.0.1:8000/recommendation/

Django Version: 2.0.7
Python Version: 3.7.0
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'bootstrap3',
 'reviews',
 'registration']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback:

File "C:\Users\tymot\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\core\handlers\exception.py" in inner
  35.             response = get_response(request)

File "C:\Users\tymot\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\core\handlers\base.py" in _get_response
  128.                 response = self.process_exception_by_middleware(e, request)

File "C:\Users\tymot\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\core\handlers\base.py" in _get_response
  126.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "C:\Users\tymot\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\contrib\auth\decorators.py" in _wrapped_view
  21.                 return view_func(request, *args, **kwargs)

File "C:\Users\tymot\Desktop\Cd-12.50-20.08\env\my_app\winerama\reviews\views.py" in user_recommendation_list
  89.         reverse=True

Exception Type: TypeError at /recommendation/
Exception Value: '<' not supported between instances of 'method' and 'method'

I created everything according to the steps in the tutorial. 我根据教程中的步骤创建了所有内容。

File models.py 文件models.py

from django.db import models
from django.contrib.auth.models import User
import numpy as np


class Wine(models.Model):
    name = models.CharField(max_length=200)

    def average_rating(self):
        all_ratings = [list(map(lambda x: x.rating, self.review_set.all()))]
        return np.mean(all_ratings)

    def __unicode__(self):
        return self.name


class Review(models.Model):
    RATING_CHOICES = (
        (1, '1'),
        (2, '2'),
        (3, '3'),
        (4, '4'),
        (5, '5'),
    )
    wine = models.ForeignKey(Wine, on_delete=models.CASCADE)
    pub_date = models.DateTimeField('date published')
    user_name = models.CharField(max_length=100)
    comment = models.CharField(max_length=200)
    rating = models.IntegerField(choices=RATING_CHOICES)

class Cluster(models.Model):
    name = models.CharField(max_length=100)
    users = models.ManyToManyField(User)

    def get_members(self):
        return "\n".join([u.username for u in self.users.all()])

Next i added admin.py and create 3 klaster with users in '/admin'. 接下来,我添加了admin.py并在“ / admin”中与用户一起创建了3个klaster。

from django.contrib import admin

from .models import Wine, Review, Cluster

class ReviewAdmin(admin.ModelAdmin):
    model = Review
    list_display = ('wine', 'rating', 'user_name', 'comment', 'pub_date')
    list_filter = ['pub_date', 'user_name']
    search_fields = ['comment']


class ClusterAdmin(admin.ModelAdmin):
    model = Cluster
    list_display = ['name', 'get_members']


admin.site.register(Wine)
admin.site.register(Review, ReviewAdmin)
admin.site.register(Cluster, ClusterAdmin)

My file views.py 我的文件views.py

@login_required
def user_recommendation_list(request):
    # get request user reviewed wines
    user_reviews = Review.objects.filter(user_name=request.user.username).prefetch_related('wine')
    user_reviews_wine_ids = set(map(lambda x: x.wine.id, user_reviews))

    # get request user cluster name (just the first one righ now)
    user_cluster_name = \
        User.objects.get(username=request.user.username).cluster_set.first().name

    # get usernames for other memebers of the cluster
    user_cluster_other_members = \
        Cluster.objects.get(name=user_cluster_name).users \
            .exclude(username=request.user.username).all()
    other_members_usernames = set(map(lambda x: x.username, user_cluster_other_members))

    # get reviews by those users, excluding wines reviewed by the request user
    other_users_reviews = \
        Review.objects.filter(user_name__in=other_members_usernames) \
            .exclude(wine__id__in=user_reviews_wine_ids)
    other_users_reviews_wine_ids = set(map(lambda x: x.wine.id, other_users_reviews))

    # then get a wine list including the previous IDs, order by rating
    wine_list = sorted(
        list(Wine.objects.filter(id__in=other_users_reviews_wine_ids)),
        key=lambda x: x.average_rating,
        reverse=True
    )

    return render(
        request,
        'reviews/user_recommendation_list.html',
        {'username': request.user.username, 'wine_list': wine_list}
    )

I will mark that when I try use simple version everything works fine. 我将标记为当我尝试使用简单版本时,一切正常。

@login_required
def user_recommendation_list(request):
    # get this user reviews
    user_reviews = Review.objects.filter(user_name=request.user.username).prefetch_related('wine')
    # from the reviews, get a set of wine IDs
    user_reviews_wine_ids = set(map(lambda x: x.wine.id, user_reviews))
    # then get a wine list excluding the previous IDs
    wine_list = Wine.objects.exclude(id__in=user_reviews_wine_ids)

    return render(
        request,
        'reviews/user_recommendation_list.html',
        {'username': request.user.username,'wine_list': wine_list}
    )

My error is at this stage (2.5) of the tutorial. 我的错误是在本教程的这一阶段(2.5) Stage 2.4 works good. 2.4阶段效果很好。 Everything indicates that something is wrong in views.py. 一切都表明views.py中有问题。

Any help will be very appreciated. 任何帮助将不胜感激。

The sorted() function accepts function key that returns value. sorted()函数接受返回值的功能key Seems like x.average_rating is method, not the value. 好像x.average_rating是方法,而不是值。 So you have 2 choices 所以你有2个选择

  • add () after x.average_rating 在x.average_rating之后添加()
  • convert x.average_rating to property 将x.average_rating转换为属性

There is a difference between a method and the value a method returns. 方法和方法返回的值之间存在差异。 Here in your Wine model, we see: 在您的Wine模型中,我们看到:

from django.db.models import Avg

class Wine(models.Model):
    name = models.CharField(max_length=200)

    def average_rating(self):
        return self.review_set.aggregate(
            mean=Avg('rating')
        )['mean']

    def __unicode__(self):
        return self.name

(I rewrote it to make an efficienty query, instead of Python/Django/Numpy let do the work). (我重写了它以进行高效查询,而不是让Python / Django / Numpy来完成工作)。

If you now have a Wine object named some_wine , then you do not get the average rating here with some_wine.average_rating , since this will return a method, but by calling the function, so some_wine.average_rating () . 如果您现在有一个名为some_wineWine对象,那么您在这里不会获得some_wine.average_rating的平均评分,因为这将返回一个方法,而是通过调用函数some_wine.average_rating ()

There are some options here: 这里有一些选项:

  1. calling the function in the lambda expression : lambda表达式中调用函数:

     wine_list = sorted( list(Wine.objects.filter(id__in=other_users_reviews_wine_ids)), key=lambda x: x.average_rating () , reverse=True ) 
  2. define the method as a property, in that case, you no longer call the function, it is the called behind the curtains, so: 将方法定义为属性,在这种情况下,您不再调用函数,而是在幕后进行调用,因此:

     from django.db.models import Avg class Wine(models.Model): name = models.CharField(max_length=200) @property def average_rating(self): return self.review_set.aggregate( mean= Avg('rating') )['mean'] def __unicode__(self): return self.name 
  3. use Wine.average_rating as key, since then it is a function that is called with instances: 使用Wine.average_rating作为键,因为这是一个实例调用的函数:

     wine_list = sorted( list(Wine.objects.filter(id__in=other_users_reviews_wine_ids)), key= Wine.average_rating , reverse=True ) 
  4. order the Wine objects already by the database, by using .annotate(..) : 订购 Wine的数据库对象已经通过使用.annotate(..)

     wine_list = Wine.objects.filter( id__in=other_users_reviews_wine_ids ).annotate( mean=Avg('rating') ).order_by('-rating') 

The latest approach is probably the most efficient, since a database typically is optimized for such queries, furthermore this will get done by a single query. 最新的方法可能是最有效的,因为数据库通常针对此类查询进行了优化,此外,这将通过单个查询来完成。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 '>=' 在 'method' 和 'int' 的实例之间不被支持 - '>=' not supported between instances of 'method' and 'int' TypeError:“方法”和“方法”的实例之间不支持“&gt;” - TypeError: '>' not supported between instances of 'method' and 'method' 类型错误:“方法”和“int”的实例之间不支持“&gt;” - TypeError: '>' not supported between instances of 'method' and 'int' TypeError:“浮点”和“方法”的实例之间不支持“&gt;” - TypeError: '>' not supported between instances of 'float' and 'method' TypeError:“方法”和“浮点”的实例之间不支持“&gt; =” - TypeError: '>=' not supported between instances of 'method' and 'float' 错误:“方法”和“int”的实例之间不支持“&gt;” - Error: '>' not supported between instances of 'method' and 'int' &#39;method-wrapper&#39;和&#39;int&#39;实例之间不支持&#39;&gt;&#39; - '>' not supported between instances of 'method-wrapper' and 'int' TypeError: '&gt;' 在 'method' 和 'int' 的实例之间不支持,但在这种情况下,'method' 是一个数字 - TypeError: '>' not supported between instances of 'method' and 'int', but in this case the 'method' is a number 比较Python中的两个日期对象:TypeError:&#39;datetime.date&#39;和&#39;method&#39;实例之间不支持&#39;&lt;&#39; - Comparing two date objects in Python: TypeError: '<' not supported between instances of 'datetime.date' and 'method' TypeError:“ builtin_function_or_method”和“ dict”的实例之间不支持“&gt;” - TypeError: '>' not supported between instances of 'builtin_function_or_method' and 'dict'
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM