从0开始搭建完整的电影推荐系统网站一(Python+Django)

读研这么久搞了不少推荐算法相关的东西,但重心都放在算法研究和实现上了。所以一直想做一个完整的带有人机交互的推荐网站,可惜的是之前能找到的资料都是JAVA WEB,对环境要求高,而且用的技术栈太多,相当繁琐,导致一直没有成功。最近终于在网上看到一本神书《Practical Recommender Systems; Kim Falk;January 2019》。不仅有算法,还有前后端实现。所以,中央决定了,就让我来写个利用Django做WEB框架的电影推荐系统。(PYTHON3+DJANGO


一.项目整体结构
1.Main Page(主页)

  • 卡牌式展示电影的区域
  • 每个电影的详情介绍
  • 要有个人推荐功能
  • 要有基于电影类型分类的列表

2.详情页

  • 电影海报
  • 电影描述
  • 电影评分

3.类别页

  • 有和主页一样的结构
  • 基于类别的专门的推荐

具体来说,MovieGEEKS是前端交互用的。Analytics是连接作用,监控其他部分,后面再说。collector是用来收集用户信息的(收集隐私的,哈哈哈),数据放到evidence数据库中。Recs是核心,提供推荐给网站。Recommendation builder是预先计算的推荐(离线推荐?暂时这么翻译吧)。大概主页长这样:

好!到此大概对整体框架有个感觉了。

二. 创建项目

我用Pycharm先创建一个Django项目,起名为MovieAngelSite

三. 创建应用

创建app,movieangel

在terminal里输入:

python manage.py startapp movieangel

四. 定义模型类

  • 有一个数据表,就有一个模型类与之对应
  • 打开models.py文件,定义模型类
  • 引入包from django.db import models
  • 模型类继承自models.Model类
  • 说明:不需要定义主键列,在生成时会自动添加,并且值为自动增长
  • 当输出对象时,会调用对象的str方法
  • 自动生成的表名为app名和模型的小写名称的组合(用下划线_组合)
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models

# Create your models here.

class Genre(models.Model):
    name = models.CharField(max_length=64)

    def __str__(self):
        return self.name


class Movie(models.Model):
    movie_id = models.CharField(max_length=16, unique=True, primary_key=True)
    title = models.CharField(max_length=128)
    year = models.IntegerField(null=True)
    genres = models.ManyToManyField(Genre, related_name='movies', db_table='movie_genre')

    def __str__(self):
        return self.title

五. 生成数据表

  • 激活模型:编辑settings.py文件,将movieangel应用加入到installed_apps中
  • 修改USE_TZ = False

  • 生成迁移文件:根据模型类生成sql语句
python manage.py makemigrations
  • 执行迁移:执行sql语句生成数据表
python manage.py migrate

 六. 视图

  • 在django中,视图对WEB请求进行回应
  • 视图接收reqeust对象作为第一个参数,包含了请求的信息
  • 视图就是一个Python函数,被定义在views.py中

首先,去https://www.themoviedb.org/account/signup这个网站注册下,拿到自己的api_key。 然后再文件根目录下,创建文件.prs,在里面加上

{ "themoviedb_apikey": "你的API_KEY"}

注意要加上“ ”双引号。
 

接着,在movieangel的views.py里加上

# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import uuid, random
import json
from django.shortcuts import render
from django.views.decorators.csrf import ensure_csrf_cookie
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from movieangel.models import Movie, Genre


# Create your views here.
# 默认首页
@ensure_csrf_cookie
def index(request):
    genre_selected = request.GET.get('genre')

    api_key = get_api_key()

    if genre_selected:
        selected = Genre.objects.filter(name=genre_selected)[0]
        movies = selected.movies.order_by('-year', 'movie_id')
    else:
        movies = Movie.objects.order_by('-year', 'movie_id')

    genres = get_genres()

    page_number = request.GET.get("page", 1)
    page, page_end, page_start = handle_pagination(movies, page_number)

    context_dict = {'movies': page,
                    'genres': genres,
                    'api_key': api_key,
                    'session_id': session_id(request),
                    'user_id': user_id(request),
                    'pages': range(page_start, page_end),
                    }

    return render(request, 'movieangel/index.html', context_dict)

# 分页
def handle_pagination(movies, page_number):
    paginate_by = 18

    paginator = Paginator(movies, paginate_by)

    try:
        page = paginator.page(page_number)
    except PageNotAnInteger:
        page_number = 1
        page = paginator.page(page_number)
    except EmptyPage:
        page = paginator.page(paginator.num_pages)

    page_number = int(page_number)
    page_start = 1 if page_number < 5 else page_number - 3
    page_end = 6 if page_number < 5 else page_number + 2
    return page, page_end, page_start


# 获得API_KEY
def get_api_key():
    # Load credentials
    cred = json.loads(open(".prs").read())
    return cred['themoviedb_apikey']

# 获得所有电影类型名
def get_genres():
    return Genre.objects.all().values('name').distinct()

# 设置session_id
def session_id(request):
    if not "session_id" in request.session:
        request.session["session_id"] = str(uuid.uuid1())

    return request.session["session_id"]

# 设置usr_id,没有就随机出来一个
def user_id(request):
    user_id = request.GET.get("user_id")

    if user_id:
        request.session['user_id'] = user_id

    if not "user_id" in request.session:
        request.session['user_id'] = random.randint(10000000000, 90000000000)

    print("ensured id: ", request.session['user_id'])
    return request.session['user_id']

配置URLconf

  • 在Django中,定义URLconf包括正则表达式、视图两部分
  • Django使用正则表达式匹配请求的URL,一旦匹配成功,则调用应用的视图
  • 注意:只匹配路径部分,即除去域名、参数后的字符串
  • 在MovieAngelSite/urls.py修改为
from django.conf.urls import url,include
from django.contrib import admin
from movieangel import views

urlpatterns = [
    url(r'^$', views.index, name='index'),
    url(r'^movies/', include('movieangel.urls')),
    url(r'^admin/', admin.site.urls),
]

加入模板

  • 模板是html页面,可以根据视图中传递的数据填充值
  • 创建模板的目录,static目录

  • 修改settings.py文件
加入
TEMPLATE_DIR = os.path.join(BASE_DIR, 'templates')
STATIC_DIR = os.path.join(BASE_DIR, &#
评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值