(window.webpackJsonp=window.webpackJsonp||[]).push([[171],{695:function(t,s,a){"use strict";a.r(s);var e=a(56),n=Object(e.a)({},(function(){var t=this,s=t.$createElement,a=t._self._c||s;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"showing-only-the-logged-in-user-s-movies"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#showing-only-the-logged-in-user-s-movies"}},[t._v("#")]),t._v(" Showing only the logged in user's movies")]),t._v(" "),a("div",{staticClass:"custom-block tip"},[a("p",{staticClass:"custom-block-title"},[t._v("TIP")]),t._v(" "),a("p",[t._v("List of all code changes made in this lecture: "),a("a",{attrs:{href:"https://diff-store.com/diff/section14__17_showing_only_user_movies",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://diff-store.com/diff/section14__17_showing_only_user_movies"),a("OutboundLink")],1)])]),t._v(" "),a("h2",{attrs:{id:"adding-the-login-required-decorator"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#adding-the-login-required-decorator"}},[t._v("#")]),t._v(" Adding the "),a("code",[t._v("login_required")]),t._v(" decorator")]),t._v(" "),a("p",[t._v("In the lecture on Adding a "),a("code",[t._v("login_required")]),t._v(" decorator, in section 13, I said that the decorator code would come in handy in many future projects. This is one such project, so let's bring the decorator in to "),a("code",[t._v("routes.py")]),t._v(":")]),t._v(" "),a("div",{staticClass:"language-py extra-class"},[a("pre",{pre:!0,attrs:{class:"language-py"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" functools\n\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("login_required")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("route"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token decorator annotation punctuation"}},[t._v("@functools"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("wraps")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("route"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("route_wrapper")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("args"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("**")]),t._v("kwargs"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" session"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("get"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"email"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("is")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("None")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" redirect"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("url_for"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('".login"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" route"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("args"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("**")]),t._v("kwargs"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" route_wrapper\n")])])]),a("p",[t._v("Then we can use it to decorate a few of our endpoints:")]),t._v(" "),a("ul",[a("li",[a("code",[t._v("index")])]),t._v(" "),a("li",[a("code",[t._v("add_movie")])]),t._v(" "),a("li",[a("code",[t._v("edit_movie")])]),t._v(" "),a("li",[a("code",[t._v("watch_today")])]),t._v(" "),a("li",[a("code",[t._v("rate_movie")])])]),t._v(" "),a("p",[t._v("Remember that the "),a("code",[t._v("@login_required")]),t._v(" decorator should be applied between the "),a("code",[t._v("@pages.route(...)")]),t._v(" decorator and the "),a("code",[t._v("def function_name(...)")]),t._v(" line.")]),t._v(" "),a("h2",{attrs:{id:"adding-movies-to-this-user-s-movie-list"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#adding-movies-to-this-user-s-movie-list"}},[t._v("#")]),t._v(" Adding movies to this user's movie list")]),t._v(" "),a("p",[t._v("Since we are going to require login before being able to add a movie, we will know the user that is making the request to the "),a("code",[t._v("add_movie")]),t._v(" endpoint.")]),t._v(" "),a("p",[t._v("Since we know the user, we can add the newly-added movie to their profile by adding it to this user's "),a("code",[t._v("movies")]),t._v(" list.")]),t._v(" "),a("p",[t._v("In the "),a("code",[t._v("add_movie")]),t._v(" endpoint I'm adding these lines:")]),t._v(" "),a("div",{staticClass:"language-py extra-class"},[a("pre",{pre:!0,attrs:{class:"language-py"}},[a("code",[t._v("current_app"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("db"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("user"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("update_one"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"_id"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" session"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"user_id"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"$push"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"movies"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" movie"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("_id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),a("p",[t._v("Using "),a("code",[t._v('session["user_id"]')]),t._v(", we can go directly into MongoDB, and use "),a("code",[t._v("$push")]),t._v(" to add a new value to the "),a("code",[t._v("movies")]),t._v(" list. Note that we didn't need to create a "),a("code",[t._v("User")]),t._v(" object since all we need is already in the "),a("code",[t._v("session")]),t._v(".")]),t._v(" "),a("h2",{attrs:{id:"showing-only-this-user-s-movies-in-the-index"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#showing-only-this-user-s-movies-in-the-index"}},[t._v("#")]),t._v(" Showing only this user's movies in the "),a("code",[t._v("index")])]),t._v(" "),a("p",[t._v("At the moment our "),a("code",[t._v("index")]),t._v(" endpoint does this to load movie data:")]),t._v(" "),a("div",{staticClass:"language-py extra-class"},[a("pre",{pre:!0,attrs:{class:"language-py"}},[a("code",[t._v("movie_data "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" current_app"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("db"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("movie"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("find"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),a("p",[t._v("Now want to load the user's data, and then check the user's movies and only load the movies in that list:")]),t._v(" "),a("div",{staticClass:"language-py extra-class"},[a("pre",{pre:!0,attrs:{class:"language-py"}},[a("code",[t._v("user_data "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" current_app"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("db"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("user"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("find_one"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"email"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" session"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"email"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nuser "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" User"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("**")]),t._v("user_data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\nmovie_data "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" current_app"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("db"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("movie"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("find"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"_id"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"$in"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" user"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("movies"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),a("p",[t._v("Using "),a("code",[t._v("$in")]),t._v(" with MongoDB only gives us movies whose "),a("code",[t._v("_id")]),t._v(" property is one of the "),a("code",[t._v("user.movies")]),t._v(".")]),t._v(" "),a("p",[t._v("And with that, we've added personalization to our app. Instead of showing all movies to everyone, we only show this user's movies.")]),t._v(" "),a("p",[t._v("Note that we could add another endpoint to view "),a("em",[t._v("all movies added by all users")]),t._v(", and that would be identical to our "),a("code",[t._v("index")]),t._v(" endpoint before we made changes. That would be useful if we wanted to allow comments or reviews for movies added by other users, for example.")])])}),[],!1,null,null,null);s.default=n.exports}}]);