How to Edit User Profile Both Django User and Custom User Fields

Posted By Amit Patel | 31-Dec-2018

Quick Summary:-

In this blog, we will learn how to edit User profile both Django User and custom User fields. And the custom User model is UserProfile.

 

Prerequisites:-

  1. I have used python version 3.6
  2. Django version 2.0.2
  3. Operating System Ubuntu 16.04
  4. MySQL
  5. IDE - pycharm-community-2018.2.5


Let's start to create Django project:- 

 

#  This command will create a Django project with demopythonproject name.
         $ django-admin.py startprojectdemopythonproject

#  View the list of files or folders.
         $ ls

#  Select dictory/folder.
         $ cd demopythonproject

 

Now, create accounts app:-

 

#  In Django, we create app module "accounts" using this command.

$ python3.6 manage.py startapp accounts


And run the project-

 

#  Using this command, we will start the project.

$ python3.6 manage.py runserver

If we navigate this Url http://127.0.0.1:8000. We'll see Django welcome page.

Add "accounts" at the bottom of "INSTALLED_APPS". And add the "AUTH_PROFILE_MODULE" config at the bottom of the entire file.

We will add "accounts" app in settings.py and use the "AUTH_USER_MODEL" config to tell Django to use our another model. And our another model will UserProfile.

 

                ## demopythonproject/settings.py

                INSTALLED_APPS = [
                    ......
                    ......
                    ......
                    ......
                    'accounts',
                ]
                ......
                ......
                ......

                AUTH_PROFILE_MODULE = "accounts.UserProfile"

 


Update database configuration in settings.py-

 

                ## demopythonproject/settings.py

                DATABASES = {
                    'default': {
                        'ENGINE': 'django.db.backends.mysql',
                        'NAME': 'custom',
                        'USER': 'root',
                        'PASSWORD': 'root',
                        'HOST': 'localhost',
                        'PORT': '3306',
                    }
                }

where 'custom' is database name. And we will create 'custom' database through terminal.


In modles.py, we will add UserProfile model.

UserProfile model, that means it is a entity class. And created "accounts_userprofile" table in "custom" database. Where all entry of UserProfile will be store.

 ## accounts/modles.py

from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save

# Create your models here.

class UserProfileManager(models.Manager):
         pass

class UserProfile(models.Model):
         #user = models.OneToOneField(User)
         user = models.OneToOneField(User, on_delete=models.CASCADE)
         description = models.CharField(max_length=100, default='')
         city = models.CharField(max_length=100, default='')
         website = models.URLField(default='')
         phoneNumber = models.IntegerField(default=0)
         image = models.ImageField(upload_to='profile_image' , blank=True)


         def __str__(self):
         return self.user.username


def createProfile(sender, **kwargs):
         if kwargs['created']:
         user_profile = UserProfile.objects.created(user=kwargs['instance'])

         post_save.connect(createProfile, sender=User)

 

In forms.py:-

Django form is a nice thing that we can create a ModelForm which will save the result of the form to the model exactly what we want to do.

## accounts/forms.py

from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from django.forms import ModelForm

from accounts.models import UserProfile

class EditProfileForm(ModelForm):
         class Meta:
        model = User
         fields = (
                 'email',
                 'first_name',
                 'last_name'
                )
class ProfileForm(ModelForm):
         class Meta:
         model = UserProfile
         fields = ('city', 'description', 'phoneNumber', 'website', 'image') #Note that we didn't mention user field here.


In views.py:-

In views.py, we can write our custom view for our HTML templates and will use the ORM to get the data from the database.

## accounts/views.py

from django.shortcuts import render, redirect
from datetime import datetime
from accounts.forms import (EditProfileForm, ProfileForm)
from django.contrib.auth import update_session_auth_hash
from django.contrib.auth.decorators import login_required


@login_required
def edit_profile(request):
    if request.method == 'POST':
        form = EditProfileForm(request.POST, instance=request.user)
        profile_form = ProfileForm(request.POST, request.FILES, instance=request.user.userprofile)  # request.FILES is show the selected image or file

        if form.is_valid() and profile_form.is_valid():
            user_form = form.save()
            custom_form = profile_form.save(False)
            custom_form.user = user_form
            custom_form.save()
            return redirect('accounts:view_profile')
    else:
        form = EditProfileForm(instance=request.user)
        profile_form = ProfileForm(instance=request.user.userprofile)
        args = {}
        # args.update(csrf(request))
        args['form'] = form
        args['profile_form'] = profile_form
        return render(request, 'accounts/edit_profile.html', args)


In urls.py:-

 

## accounts/urls.py

from django.conf.urls import patterns, url

urlpatterns = patterns('accounts.views',
                       url(r'^view_profile/$', 'view_profile', name ='view_profile'),
                       url(r'^view_profile/edit_profile/$', 'edit_profile', name ='edit_profile')

 

In the accounts app, we make templates folder and within the templates folder create base.html:-

 

## accounts/templates/base.html

<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
    {% block head %}
    <title>Base</title>
    {% endblock %}
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
    {% if user.is_authenticated %}
    <nav class="navbar navbar-inverse">
        <div class="container-fluid">
            <div class="navbar-header">
                <a class="navbar-brand" href="#"><strong>Oodles</strong></a>
            </div>
            <ul class="nav navbar-nav">
                <li><a href="{% url 'home:home' %}">Home</a></li>
                <li><a href="{% url 'accounts:view_profile'%}">Profile</a></li>
                <li><a href="{% url 'blog:blog' %}">Blog</a></li>
            </ul>
            <ul class="nav navbar-nav navbar-right">
                <li><a href="{% url 'accounts:view_profile'%}"><span class="glyphicon glyphicon-user"></span>Hello {{ user }} !!</a></li>
                <li><img src="{{ user.userprofile.image.url}}" width="50" height="50"></li>
                <li><a href="{% url 'accounts:logout' %}"><span class="glyphicon glyphicon-log-out"></span> Logout</a></li>
            </ul>
        </div>
    </nav>
    {%else%}
    <nav class="navbar navbar-inverse">
        <div class="container-fluid">
            <div class="navbar-header">
                <a class="navbar-brand" href="#"><strong>Oodless</strong></a>
            </div>
            <ul class="nav navbar-nav">
                <li class="active"><a href="{%url 'home:home'%}">Home</a></li>
                <li><a href="#">Profile</a></li>
                <li><a href="#">Contact</a></li>
            </ul>
            <ul class="nav navbar-nav navbar-right">
                <li><a href="{% url 'accounts:register' %}"><span class="glyphicon glyphicon-user"></span> Sign Up</a></li>
                <li><a href="{% url 'accounts:login' %}"><span class="glyphicon glyphicon-log-in"></span> Login</a></li>
            </ul>
        </div>
    </nav>
    </nav>
    </div>
    {% endif %}
    {% block body %}
    <h1>Base</h1>
    {% endblock %}
</body>
</html>

In templates folder make another accounts folder.
Now we create edit_profile.html and view_profile.html file in accounts folder.

 

## accounts/templates/accounts/edit_profile.html

{% extends 'base.html' %}

{% block head %}
<title>Profile</title>
{% endblock %}

{% block body %}
<div class="container">
    <form method="post" enctype="multipart/form-data">
        {% csrf_token %}
        <table>
        {{ form.as_table }}
        {{ profile_form.as_table }}
        </table>
        <button type="submit">Submit</button>
    </form>
    <br>
</div>

{% endblock %}
## accounts/templates/accounts/view_profile.html
{% extends 'base.html' %}
{% block head %} Profile

{%endblock%}

{%block body%}

Profile

Username: {{ user }} First name: {{ user.first_name }} Last name: {{ user.last_name }} Email: {{ user.email }} Description: {{ user.userprofile.description }} Phone: {{ user.userprofile.phoneNumber }} City: {{ user.userprofile.city }} Website: {{ user.userprofile.website }} {%endblock%}

In urls.py:-

 

 

## demopythonproject/urls.py

from django.conf.urls import include, url
from django.contrib import admin
from demopythonproject import views
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
                  url(r'^accounts/', include('accounts.urls', namespace='accounts')),
              ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

 

Now we can run make migrations and migrate commands to create a new database that uses the custom user model.

                 $ python3.6 manage.py makemigrations accounts
                 $ python3.6 manage.py migrate


Conclusion:-
                   In this article, we have covered how to edit User profile both Django User and custom User fields.

Reference:-
              External links to the source code-
              1)- https://www.youtube.com/watch?v=Fc2O3_2kax8&list=PLw02n0FEB3E3VSHjyYMcFadtQORvl1Ssj

Request for Proposal

Recaptcha is required.

Sending message..