ホーム>source

ウィネラマレコメンダーをやろうとしているチュートリアル 。解決できないエラーが発生しました。 「推奨リスト」タブに移動しようとすると、ブラウザから次のエラーが返されました。

エラー 

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'

チュートリアルの手順に従ってすべてを作成しました。

ファイル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()])

次に追加しましたadmin.py 「/ admin」にユーザーがいる3つのクラスターを作成します。

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)

私のファイル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}
    )

単純なバージョンを使用しようとすると、すべてが正常に機能することを示します。

@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}
    )

私のエラーはこれですステージ(2.5) チュートリアルの。ステージ2.4は正常に機能します。 すべては、views.pyで何かが間違っていることを示しています。

どんな助けも大歓迎です。

あなたの答え
  • 解決した方法 # 1

    ザ・ウィズウィズ  関数は関数 sorted() を受け入れます  値を返します。 x.average_ratingはメソッドであり、値ではないようです。だからあなたは2つの選択肢があります

    x.average_ratingの後に()を追加します

    x.average_ratingをプロパティに変換する

  • 解決した方法 # 2

    には違いがあります方法 およびメソッドが返す値。ここにあなたの key で  モデル、私達は見る:

    Wine
    
    

    (Python/Django/Numpyではなく、効率的なクエリを作成するように書き直しました)。

    あなたが今 from django.db.models importAvg 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 を持っている場合   Wine という名前のオブジェクト 、ここでは some_wine で平均評価を得られません 、これはメソッドを返しますが、呼ぶ 関数なので、 some_wine.average_rating

    ここにはいくつかのオプションがあります:

    で関数を呼び出すラムダ式

    some_wine.average_rating()
    
    

    メソッドをプロパティとして定義します。その場合、もうコール 関数、それはカーテンの後ろで呼び出されるので:

    wine_list = sorted(
        list(Wine.objects.filter(id__in=other_users_reviews_wine_ids)),
        key=lambda x: x.average_rating(),
        reverse=True
    )
    
    

    from django.db.models importAvg 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 を使用する  キーとして、それはそれである関数です呼ばれた インスタンスで:

    Wine.average_rating
    
    

    注文  wine_list = sorted( list(Wine.objects.filter(id__in=other_users_reviews_wine_ids)), key=Wine.average_rating, reverse=True )   Wine を使用して、既にデータベースにあるオブジェクト :

    .annotate(..)
    
    

    データベースは通常そのようなクエリに対して最適化されているため、おそらく最新のアプローチが最も効率的です。さらに、これはシングル クエリ。

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

関連記事

  • 前へ java - JPAクエリ:サブクエリをグループ化条件に結合する
  • 次へ RのdoParallelでforeachループでラスタースタックを使用する