DEV Community

Cover image for Build an AI Fashion Assistant in Django - Full Tutorial (w/ videos)
Dom Vacchiano
Dom Vacchiano

Posted on

Build an AI Fashion Assistant in Django - Full Tutorial (w/ videos)

๐Ÿง ๐Ÿงฅ Build an AI-Powered Fashion Assistant with Django

In this tutorial, weโ€™ll walk step-by-step through creating a stylish AI Weather-Based Fashion Assistant using Django, WeatherAPI, and OpenAI. By the end, youโ€™ll have a fully functional app that stores clothing items and generates stylish outfit suggestions based on the weather in your area.


๐ŸŽฏ Final Project Showcase

Our finished app allows users to:

  • Add clothing items to a personal "closet"
  • View and manage items via Django Admin
  • Get daily outfit suggestions based on live weather data and wardrobe content using OpenAI-GPT

AI-Powered Fashion Assistant w/ Django


๐Ÿ› ๏ธ Project Setup

1. Create and Navigate into the Project Directory

mkdir ai-fashion-assistant
cd ai-fashion-assistant
Enter fullscreen mode Exit fullscreen mode

2. Open in VS Code

code .
Enter fullscreen mode Exit fullscreen mode

3. Create a Virtual Environment

py -m venv env
source env/scripts/activate  # macOS/Linux: source env/bin/activate
Enter fullscreen mode Exit fullscreen mode

๐Ÿ”— Learn more about Python virtual environments here


๐Ÿš€ Start the Django Project

4. Install Django

pip install django
Enter fullscreen mode Exit fullscreen mode

5. Start a New Django Project

django-admin startproject config .
Enter fullscreen mode Exit fullscreen mode

6. Run the Server

python manage.py runserver
Enter fullscreen mode Exit fullscreen mode

Visit http://localhost:8000 โ€” you should see the rocket ship ๐Ÿš€!


๐Ÿ“ฆ Create and Configure the App

7. Create Your First App

python manage.py startapp core
Enter fullscreen mode Exit fullscreen mode

8. Add App to Settings

Update config/settings.py:

INSTALLED_APPS = [
    ...
    'django.contrib.staticfiles',
    'core.apps.CoreConfig',
]
Enter fullscreen mode Exit fullscreen mode

๐Ÿ‘‹ First View and URL

9. Write a Simple View

# core/views.py
from django.http import HttpResponse

def index(request):
    return HttpResponse("Hello World!")
Enter fullscreen mode Exit fullscreen mode

10. Add App URL Routing

Create core/urls.py:

from django.urls import path
from core import views

urlpatterns = [
    path("closet/", views.index, name="index"),
]
Enter fullscreen mode Exit fullscreen mode

Update config/urls.py:

from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path("", include("core.urls")),
]
Enter fullscreen mode Exit fullscreen mode

๐Ÿ—ƒ๏ธ Database and Models

11. Run Initial Migrations

python manage.py migrate
Enter fullscreen mode Exit fullscreen mode

12. Create a Clothing Model

# core/models.py
from django.db import models

class Clothing(models.Model):
    title = models.CharField(max_length=200)

    def __str__(self):
        return self.title
Enter fullscreen mode Exit fullscreen mode

13. Make and Apply Migrations

python manage.py makemigrations core
python manage.py migrate
Enter fullscreen mode Exit fullscreen mode

๐Ÿš Interact with the Database

14. Django Shell Quick Test

python manage.py shell
>>> Clothing.objects.create(title="blue jeans")
>>> Clothing.objects.all()
>>> exit()
Enter fullscreen mode Exit fullscreen mode

๐Ÿ” Admin Setup

15. Create a Superuser

python manage.py createsuperuser
Enter fullscreen mode Exit fullscreen mode

16. Register Model in Admin

# core/admin.py
from django.contrib import admin
from core.models import Clothing

admin.site.register(Clothing)
Enter fullscreen mode Exit fullscreen mode

Visit http://localhost:8000/admin


๐Ÿงพ Views, Templates, and Forms

17. Show All Clothing Items

# core/views.py
from django.shortcuts import render
from django.db.models.functions import Lower
from core.models import Clothing

def index(request):
    clothing_list = Clothing.objects.all().order_by(Lower("title"))
    return render(request, "core/index.html", {"clothing_list": clothing_list})
Enter fullscreen mode Exit fullscreen mode
<!-- core/templates/core/index.html -->
<h1>My Closet</h1>
{% if clothing_list %}
<ul>
    {% for clothing_item in clothing_list %}
    <li><a href="{% url 'clothing-detail' clothing_item.id %}">{{ clothing_item.title|title }}</a></li>
    {% endfor %}
</ul>
{% endif %}
Enter fullscreen mode Exit fullscreen mode

18. Add Item via Form

Update view:

# core/views.py
from django.shortcuts import redirect

def index(request):
    if request.method == "POST":
        clothing_title = request.POST.get('clothing_item', '')
        if clothing_title:
            Clothing.objects.create(title=clothing_title)
    clothing_list = Clothing.objects.all().order_by(Lower("title"))
    return render(request, "core/index.html", {"clothing_list": clothing_list})
Enter fullscreen mode Exit fullscreen mode

Update template:

<form action="{% url 'index' %}" method="post">
    {% csrf_token %}
    <label for="clothing_item">Add Clothing Item</label>
    <input type="text" name="clothing_item" id="clothing_item">
    <input type="submit" value="Add Clothing Item">
</form>
Enter fullscreen mode Exit fullscreen mode

๐Ÿ” View & Delete Individual Items

19. Add Views and URLs

# core/views.py
def clothing_detail(request, clothing_id):
    clothing_item = Clothing.objects.get(id=clothing_id)
    return render(request, "core/clothing-detail.html", {"clothing_item": clothing_item})

def clothing_delete(request, clothing_id):
    if request.method == "POST":
        Clothing.objects.get(id=clothing_id).delete()
    return redirect("index")
Enter fullscreen mode Exit fullscreen mode
# core/urls.py
path("closet/<int:clothing_id>/", views.clothing_detail, name="clothing-detail"),
path("closet/<int:clothing_id>/delete/", views.clothing_delete, name="clothing-delete"),
Enter fullscreen mode Exit fullscreen mode
<!-- clothing-detail.html -->
<h1>{{ clothing_item.title|title }} Details</h1>
<form action="{% url 'clothing-delete' clothing_item.id %}" method="POST">
    {% csrf_token %}
    <input type="submit" value="Delete Item">
</form>
Enter fullscreen mode Exit fullscreen mode

๐ŸŒฆ๏ธ๐Ÿ”ฎ Weather + AI Stylist Integration

20. Set Up API Keys

  1. Create a free account on WeatherAPI
  2. Once you create a free account โ†’ find your API Key at the top of the page after you log in.
  3. Copy and paste it into config/settings.py

OpenAI API Setup

  1. Create a free OpenAI API account
  2. Go to Dashboard at the top menu
  3. Then API keys from the left sidebar menu and create new secret key
  4. Copy/paste the key into the django config/settings.py file
# config/settings.py
WEATHER_API_KEY = "your_weatherapi_key"
OPENAI_API_KEY = "your_openai_api_key"
Enter fullscreen mode Exit fullscreen mode

21. Install Required Packages

pip install requests openai
Enter fullscreen mode Exit fullscreen mode

22. Create the Stylist View

# core/views.py
import requests, openai
from config.settings import OPENAI_API_KEY, WEATHER_API_KEY

def stylist(request):
    location = request.GET.get('location', '')
    context = {}
    if location:
        clothes = list(Clothing.objects.all().values_list("title", flat=True))
        r = requests.get(f"http://api.weatherapi.com/v1/current.json?key={WEATHER_API_KEY}&q={location}")
        weather = r.json()

        client = openai.OpenAI(api_key=OPENAI_API_KEY)
        response = client.responses.create(
            model="gpt-4.1-mini",
            input=f"Give a stylish outfit from: {clothes}. Weather: {weather['current']['temp_f']}ยฐF, {weather['current']['condition']['text']}."
        )

        context = {
            "weather": f"Current weather in {weather['location']['name']} is {weather['current']['temp_f']}ยฐF and {weather['current']['condition']['text'].lower()}",
            "outfit": response.output_text
        }

    return render(request, "core/stylist.html", context)
Enter fullscreen mode Exit fullscreen mode

23. Create the Template

<!-- stylist.html -->
<h1>AI Weather-Based Wardrobe Stylist</h1>
<form action="{% url 'stylist' %}" method="get">
    <input type="text" name="location" placeholder="Enter your city or zip">
    <input type="submit" value="Get Outfit">
</form>

{% if weather %}
<p><strong>{{ weather }}</strong></p>
{% endif %}
{% if outfit %}
<p>{{ outfit }}</p>
{% endif %}
Enter fullscreen mode Exit fullscreen mode

24. Update URLs

path("", views.stylist, name="stylist"),
Enter fullscreen mode Exit fullscreen mode

๐Ÿงต Next Steps - Tailwind Styling

In the next part of the series, weโ€™ll explore adding Tailwind CSS styling, creating a base layout, and enhancing UX. This will make our app not only smart, but pretty-(ish).

Create html file core/templates/core/base.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>AI Stlylist</title>
    <script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
</head>
<body class="">
    <nav class="w-[75%] pt-4 mx-auto flex flex-row justify-between items-center">
        <div>
            <p class="text-3xl text-indigo-800">๐Ÿ‘–โ›… DJ AI STYLIST</p>
        </div>
        <div class="space-x-4">
            <a class="" href="{% url 'stylist' %}">My Stylist</a>
            <a href="{% url 'index' %}">My Closet</a>
        </div>
    </nav>
    {% block content %}
    {% endblock content %}
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Update core/templates/core/index.html

{% extends 'core/base.html' %}

{% block content %}
<h1 class="text-center text-2xl font-semibold mt-12">My Closet</h1>
<form action="{% url 'index' %}" method="post">
    {% csrf_token %}
    <div class="w-[50%] mx-auto flex gap-4 mt-12">
        <input type="text" name="clothing_item" id="clothing_item" placeholder="blue t-shirt" class="block w-full rounded-md bg-white px-3 py-1.5 text-base text-gray-900 outline outline-1 -outline-offset-1 outline-gray-600 placeholder:text-gray-500 focus:outline focus:outline-2 focus:-outline-offset-2 focus:outline-indigo-600 sm:text-sm/6">
        <input type="submit" value="Add Clothing Item" class="cursor-pointer rounded-md bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600">
    </div>
</form>
{% if clothing_list %}
<ul class="my-12 w-[75%] mx-auto flex justify-center flex-wrap gap-4">
    {% for clothing_item in clothing_list %}
        <li class="text-center border border-gray-400 rounded hover:bg-gray-300">
            <a href="{% url 'clothing-detail' clothing_item.id %}" class="block p-10">{{ clothing_item.title|title }}</a>
        </li>
    {% endfor %}
</ul>
{% endif %}
{% endblock content %}
Enter fullscreen mode Exit fullscreen mode

Update core/templates/core/clothing-detail.html

{% extends 'core/base.html' %}

{% block content %}
{% if clothing_item %}
<h1 class="text-2xl font-semibold mt-18 w-[50%] mx-auto text-center">{{ clothing_item.title|title }} Details</h1>
<form class="w-[50%] mx-auto my-18" action="{% url 'clothing-delete' clothing_item.id %}" method="POST">
    {% csrf_token %}
    <div class="flex justify-center items-center space-x-4">
        <p class="text-lg">delete clothing item?</p>
        <input type="submit" value="Delete Item" class="cursor-pointer rounded-md bg-red-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-red-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-red-600">
    </div>
</form>
{% endif %}
{% endblock content %}
Enter fullscreen mode Exit fullscreen mode

Update core/templates/core/stylist.html

{% extends 'core/base.html' %}

{% block content %}
<h1 class="text-xl mt-18 text-center">Enter your location below to get a weather based outfit:</h1>
<form action="{% url 'stylist' %}" method="get">
    <!-- <input type="text" name="location" id="location" placeholder="Enter your location city or zip"> -->
     <div class="w-[50%] mx-auto flex gap-4 mt-12">
         <input type="text" name="location" id="location" class="block w-full rounded-md bg-white px-3 py-1.5 text-base text-gray-900 outline outline-1 -outline-offset-1 outline-gray-600 placeholder:text-gray-500 focus:outline focus:outline-2 focus:-outline-offset-2 focus:outline-indigo-600 sm:text-sm/6" placeholder="Enter city or zip">
         <input type="submit" value="Get Outfit Idea" class="cursor-pointer rounded-md bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600">
    </div>

</div>

</form>
{% if weather %}
<div class="w-[50%] mx-auto mt-18">
    <h4 class="text-xl">{{weather}}</h4>    
</div>
{% endif %}

{% if outfit %}
<div class="w-[50%] mx-auto mt-12">
    <h4 class="text-lg font-semibold">Your personalized outfit based on the weather is:</h4>
    <p class="text-md mt-4">{{outfit}}</p>
</div>
{% endif %}
{% endblock content %}
Enter fullscreen mode Exit fullscreen mode

๐Ÿง  Summary

You've now built:

  • A Django app to manage a personal wardrobe
  • Admin interface for CRUD operations
  • AI-powered stylist using WeatherAPI and OpenAI

This project is a great starting point for more advanced features like image upload, outfit history, or even seasonal recommendations!

Top comments (1)