{"id":6152,"date":"2022-12-05T03:57:50","date_gmt":"2022-12-05T03:57:50","guid":{"rendered":"https:\/\/www.pythontutorial.net\/?page_id=6152"},"modified":"2023-08-17T09:51:36","modified_gmt":"2023-08-17T09:51:36","slug":"django-user-profile","status":"publish","type":"page","link":"https:\/\/www.pythontutorial.net\/django-tutorial\/django-user-profile\/","title":{"rendered":"Django User Profile"},"content":{"rendered":"\n<p><strong>Summary<\/strong>: in this tutorial, you&#8217;ll learn how to implement a user profile in Django applications.<\/p>\n\n\n\n<p class=\"note\">This tutorial begins where&nbsp;the&nbsp;<a href=\"https:\/\/www.pythontutorial.net\/django-tutorial\/django-password-reset\/\">Django password reset tutorial<\/a>&nbsp;left off.<\/p>\n\n\n\n<p>A user profile consists of settings and information associated with a user. In this tutorial, you&#8217;ll learn how to allow users to update their profiles in Django applications.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id='installing-the-pillow-package'>Installing the pillow package <a href=\"#installing-the-pillow-package\" class=\"anchor\" id=\"installing-the-pillow-package\" title=\"Anchor for Installing the pillow package\">#<\/a><\/h2>\n\n\n\n<p>Since we&#8217;ll deal with images, we need to install the <code>pillow<\/code> package by using the following <code>pip<\/code> command:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">pip install Pillow<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\" id='configuring-the-directory-to-store-the-uploaded-images'>Configuring the directory to store the uploaded images <a href=\"#configuring-the-directory-to-store-the-uploaded-images\" class=\"anchor\" id=\"configuring-the-directory-to-store-the-uploaded-images\" title=\"Anchor for Configuring the directory to store the uploaded images\">#<\/a><\/h2>\n\n\n\n<p>First, create a <code>media<\/code> directory in the project:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">mkdir media<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Second, add the <code>MEDIA_ROOT<\/code> and <code>MEDIA_URL<\/code> to the <code>settings.py<\/code> of the project:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">MEDIA_ROOT = BASE_DIR \/ <span class=\"hljs-string\">'media'<\/span>\nMEDIA_URL = <span class=\"hljs-string\">'\/media\/'<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>The <code><code>MEDIA_ROOT<\/code><\/code> specifies the directory that stores the uploaded image. The <code>MEDIA_URL<\/code> specifies the URL that serves the image files from the <code><code>MEDIA_ROOT<\/code><\/code> directory.<\/p>\n\n\n\n<p>Third, add the URL that serves the media files to the <code>urls.py<\/code> of the project as follows:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python shcb-code-table\"><span class='shcb-loc'><span><span class=\"hljs-keyword\">from<\/span> django.contrib <span class=\"hljs-keyword\">import<\/span> admin\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">from<\/span> django.urls <span class=\"hljs-keyword\">import<\/span> path, include\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">from<\/span> django.conf <span class=\"hljs-keyword\">import<\/span> settings\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">from<\/span> django.conf.urls.static <span class=\"hljs-keyword\">import<\/span> static\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>urlpatterns = &#91;\n<\/span><\/span><span class='shcb-loc'><span>    path(<span class=\"hljs-string\">'admin\/'<\/span>, admin.site.urls),\n<\/span><\/span><span class='shcb-loc'><span>    path(<span class=\"hljs-string\">''<\/span>,include(<span class=\"hljs-string\">'todo.urls'<\/span>)),\n<\/span><\/span><span class='shcb-loc'><span>    path(<span class=\"hljs-string\">''<\/span>,include(<span class=\"hljs-string\">'users.urls'<\/span>))\n<\/span><\/span><span class='shcb-loc'><span>]\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><mark class='shcb-loc'><span><span class=\"hljs-keyword\">if<\/span> settings.DEBUG:\n<\/span><\/mark><mark class='shcb-loc'><span>    urlpatterns += static(settings.MEDIA_URL,\n<\/span><\/mark><mark class='shcb-loc'><span>                          document_root=settings.MEDIA_ROOT)\n<\/span><\/mark><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>If the <code>DEBUG<\/code> is <code>True<\/code> in the <code>settings.py<\/code> file, the Django app will serve the media files from <code>MEDIA_URL<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id='creating-a-profile-model'>Creating a profile model <a href=\"#creating-a-profile-model\" class=\"anchor\" id=\"creating-a-profile-model\" title=\"Anchor for Creating a profile model\">#<\/a><\/h2>\n\n\n\n<p>Modify the <code>models.py<\/code> of the <code>users<\/code> app and define the <code>Profile<\/code> model as follows:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">from<\/span> django.db <span class=\"hljs-keyword\">import<\/span> models\n<span class=\"hljs-keyword\">from<\/span> django.contrib.auth.models <span class=\"hljs-keyword\">import<\/span> User\n<span class=\"hljs-keyword\">from<\/span> PIL <span class=\"hljs-keyword\">import<\/span> Image\n\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Profile<\/span><span class=\"hljs-params\">(models.Model)<\/span>:<\/span>\n    user = models.OneToOneField(User, on_delete=models.CASCADE)\n\n    avatar = models.ImageField(\n        default=<span class=\"hljs-string\">'avatar.jpg'<\/span>, <span class=\"hljs-comment\"># default avatar<\/span>\n        upload_to=<span class=\"hljs-string\">'profile_avatars'<\/span> <span class=\"hljs-comment\"># dir to store the image<\/span>\n    )\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__str__<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\n        <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-string\">f'<span class=\"hljs-subst\">{self.user.username}<\/span> Profile'<\/span>\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">save<\/span><span class=\"hljs-params\">(self, *args, **kwargs)<\/span>:<\/span>\n        <span class=\"hljs-comment\"># save the profile first<\/span>\n        super().save(*args, **kwargs)\n\n        <span class=\"hljs-comment\"># resize the image<\/span>\n        img = Image.open(self.avatar.path)\n        <span class=\"hljs-keyword\">if<\/span> img.height &gt; <span class=\"hljs-number\">300<\/span> <span class=\"hljs-keyword\">or<\/span> img.width &gt; <span class=\"hljs-number\">300<\/span>:\n            output_size = (<span class=\"hljs-number\">300<\/span>, <span class=\"hljs-number\">300<\/span>)\n            <span class=\"hljs-comment\"># create a thumbnail<\/span>\n            img.thumbnail(output_size)\n            <span class=\"hljs-comment\"># overwrite the larger image<\/span>\n            img.save(self.avatar.path)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>How it works.<\/p>\n\n\n\n<p>First, define the <code>Profile<\/code> model inherits from the <code>Model<\/code> class:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">class<\/span> <span class=\"hljs-selector-tag\">Profile<\/span>(<span class=\"hljs-selector-tag\">models<\/span><span class=\"hljs-selector-class\">.Model<\/span>):<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Second, each user has a profile and each profile belongs to a user. Therefore, the relationship between the <code>User<\/code> model and the <code>Profile<\/code> model is one-to-one. <\/p>\n\n\n\n<p>To define the <a href=\"https:\/\/www.pythontutorial.net\/django-tutorial\/django-one-to-one\/\">one-to-one relationship<\/a>,  you use the <code>OneToOneField<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">user = models.OneToOneField(User, on_delete=models.CASCADE)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>If a <code>User<\/code> is deleted, the <code>Profile<\/code> associated with the <code>User<\/code> is also deleted. This indicates in the <code>on_delete=models.CASCADE<\/code> parameter of the <code>OneToOneField()<\/code>.<\/p>\n\n\n\n<p>Third, define the <code>avatar<\/code> field that holds the avatar of the user:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">avatar = models.ImageField(\n        default=<span class=\"hljs-string\">'avatar.jpg'<\/span>, <span class=\"hljs-comment\"># default avatar<\/span>\n        upload_to=<span class=\"hljs-string\">'profile_avatars'<\/span> <span class=\"hljs-comment\"># dir to store the image<\/span>\n)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>If users haven&#8217;t uploaded avatars, the default one is <code>avatar.jpg<\/code> file. Also, we specify the directory (<code>profile_avatars<\/code>)  that will store the uploaded avatars.<\/p>\n\n\n\n<p class=\"note\">Note that you can add more fields to the <code>Profile<\/code> model like addresses, interests, etc., if needed.<\/p>\n\n\n\n<p>Fourth, download the <code>avatar.jpg<\/code> file and copy it to the <code>media<\/code> directory of the project:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"300\" height=\"302\" src=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/12\/avatar.jpg\" alt=\"\" class=\"wp-image-6155\" srcset=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/12\/avatar.jpg 300w, https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/12\/avatar-298x300.jpg 298w, https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/12\/avatar-150x150.jpg 150w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/figure>\n\n\n\n<p>Fifth, define the <code>__str__()<\/code> method that returns a string representation of the <code>Profile<\/code> model:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__str__<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\n   <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-string\">f'<span class=\"hljs-subst\">{self.user.username}<\/span> Profile'<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Sixth, define the <code>save()<\/code> method that saves the profile into the database, creates a thumbnail of the avatar, and stores it in the specified directory:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">save<\/span><span class=\"hljs-params\">(self, *args, **kwargs)<\/span>:<\/span>\n    <span class=\"hljs-comment\"># save the profile first<\/span>\n    super().save(*args, **kwargs)\n\n    <span class=\"hljs-comment\"># resize the image<\/span>\n    img = Image.open(self.avatar.path)\n    <span class=\"hljs-keyword\">if<\/span> img.height &gt; <span class=\"hljs-number\">150<\/span> <span class=\"hljs-keyword\">or<\/span> img.width &gt; <span class=\"hljs-number\">150<\/span>:\n        output_size = (<span class=\"hljs-number\">150<\/span>, <span class=\"hljs-number\">150<\/span>)\n        <span class=\"hljs-comment\"># create a thumbnail<\/span>\n        img.thumbnail(output_size)\n        \n        <span class=\"hljs-comment\"># overwrite the large image<\/span>\n        img.save(self.avatar.path)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Seventh, register the Profile in the <code>admin.py<\/code> so that we can manage the profile on the admin page:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">from<\/span> django.contrib <span class=\"hljs-keyword\">import<\/span> admin\n<span class=\"hljs-keyword\">from<\/span> .models <span class=\"hljs-keyword\">import<\/span> Profile\n\n\nadmin.site.register(Profile)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\" id='applying-the-migrations'>Applying the migrations <a href=\"#applying-the-migrations\" class=\"anchor\" id=\"applying-the-migrations\" title=\"Anchor for Applying the migrations\">#<\/a><\/h2>\n\n\n\n<p>First, make migrations by running the <code>makemigrations<\/code> command:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">python manage.py makemigrations<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Output:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-13\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">Migrations <span class=\"hljs-keyword\">for<\/span> <span class=\"hljs-string\">'users'<\/span>:\n   users\\migrations\\<span class=\"hljs-number\">0001<\/span>_initial.py\n      - Create model Profile<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-13\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Second, apply the migrations:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-14\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">python manage.py migrate<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-14\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Output:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-15\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">Operations to perform:\n   Apply all migrations: admin, auth, contenttypes, sessions, todo, users\nRunning migrations:  \n   Applying users<span class=\"hljs-number\">.0001<\/span>_initial... OK<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-15\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\" id='creating-the-myprofile-view'>Creating the MyProfile view <a href=\"#creating-the-myprofile-view\" class=\"anchor\" id=\"creating-the-myprofile-view\" title=\"Anchor for Creating the MyProfile view\">#<\/a><\/h2>\n\n\n\n<p>Define a <code>MyProfile<\/code> class-based view in the <code>views.py<\/code> file:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-16\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">from<\/span> django.views <span class=\"hljs-keyword\">import<\/span> View\n\n<span class=\"hljs-comment\"># ...<\/span>\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">MyProfile<\/span><span class=\"hljs-params\">(LoginRequiredMixin, View)<\/span>:<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">get<\/span><span class=\"hljs-params\">(self, request)<\/span>:<\/span>\n        user_form = UserUpdateForm(instance=request.user)\n        profile_form = ProfileUpdateForm(instance=request.user.profile)\n        \n        context = {\n            <span class=\"hljs-string\">'user_form'<\/span>: user_form,\n            <span class=\"hljs-string\">'profile_form'<\/span>: profile_form\n        }\n        \n        <span class=\"hljs-keyword\">return<\/span> render(request, <span class=\"hljs-string\">'users\/profile.html'<\/span>, context)\n    \n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">post<\/span><span class=\"hljs-params\">(self,request)<\/span>:<\/span>\n        user_form = UserUpdateForm(\n            request.POST, \n            instance=request.user\n        )\n        profile_form = ProfileUpdateForm(\n            request.POST,\n            request.FILES,\n            instance=request.user.profile\n        )\n\n        <span class=\"hljs-keyword\">if<\/span> user_form.is_valid() <span class=\"hljs-keyword\">and<\/span> profile_form.is_valid():\n            user_form.save()\n            profile_form.save()\n            \n            messages.success(request,<span class=\"hljs-string\">'Your profile has been updated successfully'<\/span>)\n            \n            <span class=\"hljs-keyword\">return<\/span> redirect(<span class=\"hljs-string\">'profile'<\/span>)\n        <span class=\"hljs-keyword\">else<\/span>:\n            context = {\n                <span class=\"hljs-string\">'user_form'<\/span>: user_form,\n                <span class=\"hljs-string\">'profile_form'<\/span>: profile_form\n            }\n            messages.error(request,<span class=\"hljs-string\">'Error updating you profile'<\/span>)\n            \n            <span class=\"hljs-keyword\">return<\/span> render(request, <span class=\"hljs-string\">'users\/profile.html'<\/span>, context)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-16\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>First, import the <code>View<\/code> class from <code>django.views<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-17\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">from<\/span> django.views <span class=\"hljs-keyword\">import<\/span> View<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-17\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Second, define <code><code>MyView<\/code><\/code> class that inherits from the <code>View<\/code> class. The <code><code>MyView<\/code><\/code> class has the <code>get()<\/code> and <code>post()<\/code> methods that correspond to the HTTP <code>GET<\/code> and <code>POST<\/code>.<\/p>\n\n\n\n<p>By using the <code>View<\/code> class, you don&#8217;t need to have if-else branching inside a view function to determine whether the HTTP method is GET or POST.<\/p>\n\n\n\n<p>In the <code>get()<\/code> method of the <code>MyProfile<\/code> class, we create the <code>UserUpdateForm<\/code> and <code>ProfileUpdateForm<\/code> objects and pass them to the <code>profile.html<\/code> template.<\/p>\n\n\n\n<p>In the <code>post()<\/code> method, we also create the <code>UserUpdateForm<\/code> and <code>ProfileUpdateForm<\/code> objects but pass additional data from <code>request.POST<\/code> and <code>request.FILES<\/code>.  <\/p>\n\n\n\n<p>When both forms are valid, we save them into the database, create a flash message, and redirect the user back to the profile page.<\/p>\n\n\n\n<p>If one of the forms is not valid, we create an error message and redirect the user back to the profile page, and rerender the template.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id='creating-profile-html-template'>Creating profile.html template <a href=\"#creating-profile-html-template\" class=\"anchor\" id=\"creating-profile-html-template\" title=\"Anchor for Creating profile.html template\">#<\/a><\/h2>\n\n\n\n<p>Create <code>profile.html<\/code> in the <code>templates\/users<\/code> directory that extends the <code>base.html<\/code> template:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-18\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">{% extends <span class=\"hljs-string\">'base.html'<\/span> %} \n\n{% block content %}\n\n\n&lt;div <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span>=\"<span class=\"hljs-title\">center<\/span>\"&gt;\n\t&lt;<span class=\"hljs-title\">form<\/span> <span class=\"hljs-title\">method<\/span>=\"<span class=\"hljs-title\">POST<\/span>\" <span class=\"hljs-title\">enctype<\/span>=\"<span class=\"hljs-title\">multipart<\/span>\/<span class=\"hljs-title\">form<\/span>-<span class=\"hljs-title\">data<\/span>\" <span class=\"hljs-title\">class<\/span>=\"<span class=\"hljs-title\">card<\/span>\"&gt;\n\t\t{% <span class=\"hljs-title\">csrf_token<\/span> %} \n\t\t\n\t    {% <span class=\"hljs-title\">if<\/span> <span class=\"hljs-title\">user<\/span>.<span class=\"hljs-title\">profile<\/span> %}\n\t\t\t&lt;<span class=\"hljs-title\">img<\/span> <span class=\"hljs-title\">src<\/span>=\"{{<span class=\"hljs-title\">user<\/span>.<span class=\"hljs-title\">profile<\/span>.<span class=\"hljs-title\">avatar<\/span>.<span class=\"hljs-title\">url<\/span>}}\" <span class=\"hljs-title\">alt<\/span>=\"{{ <span class=\"hljs-title\">user<\/span>.<span class=\"hljs-title\">username<\/span> }}\" <span class=\"hljs-title\">class<\/span>=\"<span class=\"hljs-title\">avatar<\/span>\"  <span class=\"hljs-title\">accept<\/span>=\".<span class=\"hljs-title\">jpg<\/span>,.<span class=\"hljs-title\">jpeg<\/span>,.<span class=\"hljs-title\">png<\/span>\"\/&gt;\n\t    {% <span class=\"hljs-title\">endif<\/span> %}\n\t    \n\t    &lt;<span class=\"hljs-title\">h2<\/span> <span class=\"hljs-title\">class<\/span>=\"<span class=\"hljs-title\">text<\/span>-<span class=\"hljs-title\">center<\/span>\"&gt;{{ <span class=\"hljs-title\">user<\/span>.<span class=\"hljs-title\">username<\/span> | <span class=\"hljs-title\">title<\/span> }}&lt;\/<span class=\"hljs-title\">h2<\/span>&gt;\n\t    &lt;<span class=\"hljs-title\">p<\/span> <span class=\"hljs-title\">class<\/span>=\"<span class=\"hljs-title\">text<\/span>-<span class=\"hljs-title\">center<\/span>\"&gt;&lt;<span class=\"hljs-title\">a<\/span> <span class=\"hljs-title\">href<\/span>=\"<span class=\"hljs-title\">mailto<\/span>:<\/span>{{user.email}}<span class=\"hljs-string\">\"&gt;{{user.email}}&lt;\/a&gt;&lt;\/p&gt;\n   \t    &lt;hr&gt;\n\t\t\n            &lt;label for=\"<\/span>email<span class=\"hljs-string\">\"&gt;Email Address:&lt;\/label&gt;\n            &lt;input type=\"<\/span>email<span class=\"hljs-string\">\" id=\"<\/span>email<span class=\"hljs-string\">\" name=\"<\/span>email<span class=\"hljs-string\">\" value=\"<\/span>{{user.email}}<span class=\"hljs-string\">\" \/&gt;\n\t\t\t\n\t\t\n\t\t&lt;label for=\"<\/span>avata<span class=\"hljs-string\">r\"&gt;Avatar:&lt;\/label&gt;\n\t\t&lt;input type=\"<\/span>file<span class=\"hljs-string\">\" name=\"<\/span>avata<span class=\"hljs-string\">r\" id=\"<\/span>avata<span class=\"hljs-string\">r\"&gt;\t\n\t\t\n\t    &lt;button type=\"<\/span>submit<span class=\"hljs-string\">\" class=\"<\/span>btn btn-primary full-width<span class=\"hljs-string\">\"&gt;Update Profile&lt;\/button&gt;\n\t\n\t&lt;\/form&gt;\n&lt;\/div&gt;\n\n{% endblock content %}<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-18\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\" id='manually-creating-a-profile'>Manually creating a profile <a href=\"#manually-creating-a-profile\" class=\"anchor\" id=\"manually-creating-a-profile\" title=\"Anchor for Manually creating a profile\">#<\/a><\/h2>\n\n\n\n<p>First, log in to the admin site using the superuser account, you&#8217;ll see the <code>Profiles<\/code> under the <code>Users<\/code> app:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"423\" height=\"114\" src=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/12\/django-user-profile-admin.png\" alt=\"\" class=\"wp-image-6157\" srcset=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/12\/django-user-profile-admin.png 423w, https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/12\/django-user-profile-admin-300x81.png 300w\" sizes=\"auto, (max-width: 423px) 100vw, 423px\" \/><\/figure>\n\n\n\n<p>Second, click Add Profile button to create a new profile for the existing user:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"748\" height=\"155\" src=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/12\/django-user-profile-add-a-new-profile.png\" alt=\"\" class=\"wp-image-6158\" srcset=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/12\/django-user-profile-add-a-new-profile.png 748w, https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/12\/django-user-profile-add-a-new-profile-300x62.png 300w\" sizes=\"auto, (max-width: 748px) 100vw, 748px\" \/><\/figure>\n\n\n\n<p>Third, add a new profile for the user John and click the Save button:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"739\" height=\"368\" src=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/12\/django-user-profile-add-profile.png\" alt=\"\" class=\"wp-image-6159\" srcset=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/12\/django-user-profile-add-profile.png 739w, https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/12\/django-user-profile-add-profile-300x149.png 300w\" sizes=\"auto, (max-width: 739px) 100vw, 739px\" \/><\/figure>\n\n\n\n<p>Django will show that the profile for the user John was added successfully.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"752\" height=\"391\" src=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/12\/django-user-profile-john-profile.png\" alt=\"\" class=\"wp-image-6160\" srcset=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/12\/django-user-profile-john-profile.png 752w, https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/12\/django-user-profile-john-profile-300x156.png 300w\" sizes=\"auto, (max-width: 752px) 100vw, 752px\" \/><\/figure>\n\n\n\n<p>If you log in as John and open the profile page <code>http:\/\/127.0.0.1:8000\/profile\/<\/code>, you&#8217;ll see the following page:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"507\" height=\"635\" src=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/12\/django-user-profile-john.png\" alt=\"\" class=\"wp-image-6161\" srcset=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/12\/django-user-profile-john.png 507w, https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/12\/django-user-profile-john-240x300.png 240w\" sizes=\"auto, (max-width: 507px) 100vw, 507px\" \/><\/figure>\n\n\n\n<p>On this form, you can update a profile by changing the email address and uploading a new avatar.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id='include-the-profile-url-in-the-header'>Include the profile URL in the header <a href=\"#include-the-profile-url-in-the-header\" class=\"anchor\" id=\"include-the-profile-url-in-the-header\" title=\"Anchor for Include the profile URL in the header\">#<\/a><\/h2>\n\n\n\n<p>Modify the <code>base.html<\/code> template to add the profile URL to the header:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-19\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-code-table\"><span class='shcb-loc'><span>{%load static %}\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-meta\">&lt;!DOCTYPE <span class=\"hljs-meta-keyword\">html<\/span>&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">html<\/span> <span class=\"hljs-attr\">lang<\/span>=<span class=\"hljs-string\">\"en\"<\/span>&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">head<\/span>&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">meta<\/span> <span class=\"hljs-attr\">charset<\/span>=<span class=\"hljs-string\">\"UTF-8\"<\/span>&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">meta<\/span> <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"viewport\"<\/span> <span class=\"hljs-attr\">content<\/span>=<span class=\"hljs-string\">\"width=device-width, initial-scale=1.0\"<\/span>&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">link<\/span> <span class=\"hljs-attr\">rel<\/span>=<span class=\"hljs-string\">\"stylesheet\"<\/span> <span class=\"hljs-attr\">href<\/span>=<span class=\"hljs-string\">\"{% static 'css\/style.css' %}\"<\/span> \/&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">title<\/span>&gt;<\/span>Todo List<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">title<\/span>&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">head<\/span>&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">body<\/span>&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">header<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"header\"<\/span>&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span>            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"container\"<\/span>&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span>            \t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a<\/span> <span class=\"hljs-attr\">href<\/span>=<span class=\"hljs-string\">\"{%url 'home'%}\"<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"logo\"<\/span>&gt;<\/span>Todo<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">a<\/span>&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span>            \t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">nav<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"nav\"<\/span>&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span>\t            \t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a<\/span> <span class=\"hljs-attr\">href<\/span>=<span class=\"hljs-string\">\"{%url 'home'%}\"<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">i<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"bi bi-house-fill\"<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">i<\/span>&gt;<\/span> Home<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">a<\/span>&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span>\t                {% if request.user.is_authenticated %}\n<\/span><\/span><span class='shcb-loc'><span>\t    \t              \t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a<\/span> <span class=\"hljs-attr\">href<\/span>=<span class=\"hljs-string\">\"{% url 'tasks' %}\"<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">i<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"bi bi-list-task\"<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">i<\/span>&gt;<\/span> My Tasks<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">a<\/span>&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span>\t    \t              \t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a<\/span> <span class=\"hljs-attr\">href<\/span>=<span class=\"hljs-string\">\"{% url 'task-create' %}\"<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">i<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"bi bi-plus-circle\"<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">i<\/span>&gt;<\/span> Create Task<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">a<\/span>&gt;<\/span>\n<\/span><\/span><mark class='shcb-loc'><span>\t\t                <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a<\/span> <span class=\"hljs-attr\">href<\/span>=<span class=\"hljs-string\">\"{% url 'profile' %}\"<\/span> <span class=\"hljs-attr\">title<\/span>=<span class=\"hljs-string\">\"Update my profile\"<\/span>&gt;<\/span>Hi {{request.user | title}}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">a<\/span>&gt;<\/span>\n<\/span><\/mark><span class='shcb-loc'><span>\t    \t                <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a<\/span> <span class=\"hljs-attr\">href<\/span>=<span class=\"hljs-string\">\"{% url 'logout' %}\"<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"btn btn-outline\"<\/span>&gt;<\/span>Logout<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">a<\/span>&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span>\t                {% else %}\n<\/span><\/span><span class='shcb-loc'><span>\t\t\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a<\/span> <span class=\"hljs-attr\">href<\/span>=<span class=\"hljs-string\">\"{% url 'login' %}\"<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"btn btn-outline\"<\/span>&gt;<\/span>Login<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">a<\/span>&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span>\t            \t        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a<\/span> <span class=\"hljs-attr\">href<\/span>=<span class=\"hljs-string\">\"{% url 'register' %}\"<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"btn btn-primary\"<\/span>&gt;<\/span>Join Now<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">a<\/span>&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span>\t                {% endif %}\n<\/span><\/span><span class='shcb-loc'><span>\t             <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">nav<\/span>&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span>            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">header<\/span>&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">main<\/span>&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span>            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"container\"<\/span>&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span>            \t{% if messages %}\n<\/span><\/span><span class='shcb-loc'><span>\t\t\t\t{% for message in messages %}\n<\/span><\/span><span class='shcb-loc'><span>\t\t\t\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"alert alert-{{message.tags}}\"<\/span>&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span>\t\t\t\t\t       {{message}}\n<\/span><\/span><span class='shcb-loc'><span>\t\t\t\t\t     <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span>\t\t\t\t\t   {% endfor %}\n<\/span><\/span><span class='shcb-loc'><span>\t\t\t\t{% endif %}\n<\/span><\/span><span class='shcb-loc'><span>            \n<\/span><\/span><span class='shcb-loc'><span>             {%block content %}\n<\/span><\/span><span class='shcb-loc'><span>             {%endblock content%}\n<\/span><\/span><span class='shcb-loc'><span>            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">main<\/span>&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">footer<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"footer\"<\/span>&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span>            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"container\"<\/span>&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span>                <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span>\u00a9 Copyright {% now \"Y\" %} by <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a<\/span> <span class=\"hljs-attr\">href<\/span>=<span class=\"hljs-string\">\"https:\/\/www.pythontutorial.net\"<\/span>&gt;<\/span>Python Tutorial<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">a<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span>            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">footer<\/span>&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">body<\/span>&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">html<\/span>&gt;<\/span>\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-19\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\" id='creating-profile-automatically'>Creating profile automatically <a href=\"#creating-profile-automatically\" class=\"anchor\" id=\"creating-profile-automatically\" title=\"Anchor for Creating profile automatically\">#<\/a><\/h2>\n\n\n\n<p>If you log in as <code>Jane<\/code> and access the profile page, you&#8217;ll get the following error:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"564\" height=\"264\" src=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/12\/django-user-profile-no-profile.png\" alt=\"\" class=\"wp-image-6164\" srcset=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/12\/django-user-profile-no-profile.png 564w, https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/12\/django-user-profile-no-profile-300x140.png 300w\" sizes=\"auto, (max-width: 564px) 100vw, 564px\" \/><\/figure>\n\n\n\n<p>The reason is that we haven&#8217;t created the profile for the user <code>Jane<\/code>. To fix this issue, we should create a profile once a user registers successfully. To implement this, we&#8217;ll use something called signals in Django.<\/p>\n\n\n\n<p>First, create <code>signals.py<\/code> file in the <code>users<\/code> app with the following code:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-20\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">from<\/span> django.db.models.signals <span class=\"hljs-keyword\">import<\/span> post_save\n<span class=\"hljs-keyword\">from<\/span> django.contrib.auth.models <span class=\"hljs-keyword\">import<\/span> User\n<span class=\"hljs-keyword\">from<\/span> django.dispatch <span class=\"hljs-keyword\">import<\/span> receiver\n<span class=\"hljs-keyword\">from<\/span> .models <span class=\"hljs-keyword\">import<\/span> Profile\n\n\n<span class=\"hljs-meta\">@receiver(post_save, sender=User)<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">create_profile<\/span><span class=\"hljs-params\">(sender, instance, created, **kwargs)<\/span>:<\/span>\n    <span class=\"hljs-keyword\">if<\/span> created:\n        Profile.objects.create(user=instance)\n\n\n<span class=\"hljs-meta\">@receiver(post_save, sender=User)<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">save_profile<\/span><span class=\"hljs-params\">(sender, instance, **kwargs)<\/span>:<\/span>\n    instance.profile.save()<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-20\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In this <code>signals.py<\/code> file:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The <code>create_profile()<\/code> function creates a new profile after a <code>User<\/code> object is created.<\/li>\n\n\n\n<li>The <code>save_profile()<\/code> function updates the profile after a <code>User<\/code> object is saved.<\/li>\n<\/ul>\n\n\n\n<p>The <code>@receiver<\/code> decorator wires up the <code>post_save<\/code> event of the <code>User<\/code> model to each function.<\/p>\n\n\n\n<p>Second, import signals to the <code>apps.py<\/code> file of the <code>users<\/code> app:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-21\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">from<\/span> django.apps <span class=\"hljs-keyword\">import<\/span> AppConfig\n\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">UsersConfig<\/span><span class=\"hljs-params\">(AppConfig)<\/span>:<\/span>\n    default_auto_field = <span class=\"hljs-string\">'django.db.models.BigAutoField'<\/span>\n    name = <span class=\"hljs-string\">'users'<\/span>\n    \n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">ready<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\n        <span class=\"hljs-keyword\">import<\/span> users.signals<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-21\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In the <code>apps.py<\/code> of the <code>users<\/code> app, we import the <code>signals.py<\/code> in the ready method of the <code>UsersConfig<\/code> class.<\/p>\n\n\n\n<p>Third, register a new user and check the profile:<\/p>\n\n\n\n<figure class=\"wp-block-video\"><video height=\"812\" style=\"aspect-ratio: 744 \/ 812;\" width=\"744\" controls src=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/12\/Django-User-Profile.mp4\"><\/video><\/figure>\n\n\n\n<p class=\"note\">You can <a href=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/12\/todo_list_10_user_profile.zip\" target=\"_blank\" rel=\"noreferrer noopener\">download the complete Django User Profile source code here<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id='summary'>Summary <a href=\"#summary\" class=\"anchor\" id=\"summary\" title=\"Anchor for Summary\">#<\/a><\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Use the Django signal to create a profile for a user automatically.<\/li>\n<\/ul>\n<div class=\"helpful-block-content\" data-title=\"\">\n\t<header>\n\t\t<div class=\"wth-question\">Was this tutorial helpful ?<\/div>\n\t\t<div class=\"wth-thumbs\">\n\t\t\t<button\n\t\t\t\tdata-post=\"6152\"\n\t\t\t\tdata-post-url=\"https:\/\/www.pythontutorial.net\/django-tutorial\/django-user-profile\/\"\n\t\t\t\tdata-post-title=\"Django User Profile\"\n\t\t\t\tdata-response=\"1\"\n\t\t\t\tclass=\"wth-btn-rounded wth-yes-btn\"\n\t\t\t>\n\t\t\t\t<svg\n\t\t\t\t\txmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t\tclass=\"feather feather-thumbs-up block w-full h-full\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\td=\"M14 9V5a3 3 0 0 0-3-3l-4 9v11h11.28a2 2 0 0 0 2-1.7l1.38-9a2 2 0 0 0-2-2.3zM7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3\"\n\t\t\t\t\t><\/path>\n\t\t\t\t<\/svg>\n\t\t\t\t<span class=\"sr-only\"> Yes <\/span>\n\t\t\t<\/button>\n\n\t\t\t<button\n\t\t\t\tdata-response=\"0\"\n\t\t\t\tdata-post=\"6152\"\n\t\t\t\tdata-post-url=\"https:\/\/www.pythontutorial.net\/django-tutorial\/django-user-profile\/\"\n\t\t\t\tdata-post-title=\"Django User Profile\"\n\t\t\t\tclass=\"wth-btn-rounded wth-no-btn\"\n\t\t\t>\n\t\t\t\t<svg\n\t\t\t\t\txmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\td=\"M10 15v4a3 3 0 0 0 3 3l4-9V2H5.72a2 2 0 0 0-2 1.7l-1.38 9a2 2 0 0 0 2 2.3zm7-13h2.67A2.31 2.31 0 0 1 22 4v7a2.31 2.31 0 0 1-2.33 2H17\"\n\t\t\t\t\t><\/path>\n\t\t\t\t<\/svg>\n\t\t\t\t<span class=\"sr-only\"> No <\/span>\n\t\t\t<\/button>\n\t\t<\/div>\n\t<\/header>\n\n\t<div class=\"wth-form hidden\">\n\t\t<div class=\"wth-form-wrapper\">\n\t\t\t<div class=\"wth-title\"><\/div>\n\t\t\t<textarea class=\"wth-message\"><\/textarea>\n\t\t\t<input type=\"button\" name=\"wth-submit\" class=\"wth-btn wth-btn-submit\" id=\"wth-submit\" \/>\n\t\t\t<input type=\"button\" class=\"wth-btn wth-btn-cancel\" value=\"Cancel\" \/>\n\t\t<\/div>\n\t<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>In this tutorial, you&#8217;ll learn how to implement a user profile in Django applications.<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":5531,"menu_order":21,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-6152","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/pages\/6152","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/comments?post=6152"}],"version-history":[{"count":0,"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/pages\/6152\/revisions"}],"up":[{"embeddable":true,"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/pages\/5531"}],"wp:attachment":[{"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/media?parent=6152"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}