Introduction
In this tutorial, you’ll learn how to build a complete Django REST API that allows you to create users with an image upload (profile picture). You’ll learn how to set up a Django project, create an app, connect to a MySQL database, create serializers and viewsets, and finally expose REST endpoints to create, retrieve, update, and delete user profiles.
Key Features
- User creation with first name, last name, email, and password
- Secure password hashing
- Image upload for profile pictures
- REST API using Django REST Framework (DRF)
- MySQL integration
Project Structure
Once your project is set up, your structure will look like this:
crudwithimage/
├── db.sqlite3 (optional)
├── manage.py
├── accounts/
│ ├── admin.py
│ ├── apps.py
│ ├── models.py
│ ├── serializers.py
│ ├── tests.py
│ ├── urls.py
│ ├── views.py
│ ├── __init__.py
│ └── migrations/
│ └── __init__.py
├── crudwithimage/
│ ├── settings.py
│ ├── urls.py
│ ├── wsgi.py
│ └── asgi.py
└── media/
└── profile_images/
└── [uploaded images]
Step 1: Install Django and DRF
pip install django djangorestframework mysqlclient pillow
Step 2: Create Django Project and App
django-admin startproject crudwithimage
cd crudwithimage
python manage.py startapp accounts
Step 3: Configure Installed Apps
In crudwithimage/settings.py
, add:
INSTALLED_APPS = [
...
"rest_framework",
"accounts",
]
Step 4: Set Up Media and MySQL
In settings.py
:
import os
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent.parent
MEDIA_URL = "/media/"
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
DATABASES = {
"default": {
"ENGINE": "django.db.backends.mysql",
"NAME": "djnagocrudimage",
"USER": "myadmin",
"PASSWORD": "Angular13#@123",
"HOST": "localhost",
"PORT": "3306",
}
}
Step 5: Define the User Model
In accounts/models.py
:
from django.db import models
from django.contrib.auth.hashers import make_password
class UserProfile(models.Model):
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
email = models.EmailField(unique=True)
password = models.CharField(max_length=128)
image = models.ImageField(upload_to="profile_images/")
def save(self, *args, **kwargs):
if not self.pk:
self.password = make_password(self.password)
super(UserProfile, self).save(*args, **kwargs)
def __str__(self):
return self.email
Step 6: Make and Apply Migrations
python manage.py makemigrations
python manage.py migrate
Step 7: Create Serializer
In accounts/serializers.py
:
from rest_framework import serializers
from .models import UserProfile
class UserProfileSerializer(serializers.ModelSerializer):
class Meta:
model = UserProfile
fields = ["id", "first_name", "last_name", "email", "password", "image"]
extra_kwargs = {
"password": {"write_only": True}
}
Step 8: Create ViewSet
In accounts/views.py
:
from rest_framework import viewsets
from .models import UserProfile
from .serializers import UserProfileSerializer
class UserProfileViewSet(viewsets.ModelViewSet):
queryset = UserProfile.objects.all()
serializer_class = UserProfileSerializer
Step 9: Register Routes
In accounts/urls.py
:
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import UserProfileViewSet
router = DefaultRouter()
router.register(r'users', UserProfileViewSet)
urlpatterns = [
path("", include(router.urls)),
]
Step 10: Include in Main URLs
In crudwithimage/urls.py
:
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path("admin/", admin.site.urls),
path("api/", include("accounts.urls")),
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Step 11: Test Your API
Run the server:
python manage.py runserver
Visit http://127.0.0.1:8000/api/users/
in your browser or use Postman.
Sample POST Request (Create User)
POST /api/users/
Content-Type: multipart/form-data
{
"first_name": "John",
"last_name": "Doe",
"email": "john@example.com",
"password": "secure123",
"image": [upload file]
}
Conclusion
You’ve successfully created a Django REST API that supports user registration and image upload. You used Django REST Framework, MySQL, and Pillow for image handling. This is a solid foundation you can expand on — for example, adding JWT auth, image validation, or deploying to production.
What’s Next?
- Add authentication (JWT with
djangorestframework-simplejwt
) - Integrate file storage services like AWS S3 or Cloudinary
- Use Django signals to send welcome emails on user creation
- Build a React frontend for the API