Добавить в корзинуПозвонить
Найти в Дзене

Как создать простого чат-бота для интернет-магазина книг на Django с использованием JSON

В этой статье мы разберем, как добавить простого чат-бота на сайт интернет-магазина книг, используя Django, JSON для хранения данных и библиотеку fuzzywuzzy для поиска с учетом опечаток. Бот будет помогать пользователям находить книги по ключевым словам, не требуя базы данных — все данные будут храниться в JSON-файле. Мы создадим интерфейс в стиле чата, где пользователь вводит запрос, а бот отвечает в реальном времени, предлагая подходящие книги из каталога. Предположим, у вас уже есть Django-проект. Если нет, создайте его: django-admin startproject bookstore
cd bookstore
python manage.py startapp shop Добавьте приложение shop в INSTALLED_APPS в bookstore/settings.py: INSTALLED_APPS = [
...
'shop',
] Создайте файл books.json в корне проекта (/bookstore/books.json) с данными о книгах: {
"books": [
{
"url": "/books/1",
"title": "Война и мир",
"keywords": ["война", "мир", "толстой", "классика"],
"description": "Эпический роман Льва Толстого о судьбах
Оглавление

В этой статье мы разберем, как добавить простого чат-бота на сайт интернет-магазина книг, используя Django, JSON для хранения данных и библиотеку fuzzywuzzy для поиска с учетом опечаток. Бот будет помогать пользователям находить книги по ключевым словам, не требуя базы данных — все данные будут храниться в JSON-файле. Мы создадим интерфейс в стиле чата, где пользователь вводит запрос, а бот отвечает в реальном времени, предлагая подходящие книги из каталога.

Что нам понадобится

  • Django: фреймворк для веб-разработки.
  • Python 3.x: убедитесь, что он установлен.
  • fuzzywuzzy: библиотека для нечеткого поиска (установите через pip install fuzzywuzzy).
  • JSON: файл с каталогом книг.
  • Базовые знания HTML, CSS и JavaScript.

Шаг 1: Настройка проекта

Предположим, у вас уже есть Django-проект. Если нет, создайте его:

django-admin startproject bookstore
cd bookstore
python manage.py startapp shop

Добавьте приложение shop в INSTALLED_APPS в bookstore/settings.py:

INSTALLED_APPS = [
...
'shop',
]

Шаг 2: Создание JSON-каталога книг

Создайте файл books.json в корне проекта (/bookstore/books.json) с данными о книгах:

{
"books": [
{
"url": "/books/1",
"title": "Война и мир",
"keywords": ["война", "мир", "толстой", "классика"],
"description": "Эпический роман Льва Толстого о судьбах людей в эпоху Наполеона"
},
{
"url": "/books/2",
"title": "Гарри Поттер и Философский камень",
"keywords": ["гарри", "поттер", "фэнтези", "магия"],
"description": "Первая книга о приключениях юного волшебника"
},
{
"url": "/books/3",
"title": "Программирование на Python",
"keywords": ["python", "программирование", "код", "it"],
"description": "Руководство по изучению Python для начинающих"
}
]
}

  • url: ссылка на страницу книги.
  • title: название книги.
  • keywords: ключевые слова для поиска.
  • description: краткое описание.

Шаг 3: Логика поиска с fuzzywuzzy

Создайте файл shop/book_search.py с классом для поиска:

import json
from fuzzywuzzy import fuzz

class BookSearch:
def __init__(self, json_path):
with open(json_path, 'r', encoding='utf-8') as f:
self.data = json.load(f)['books']

def search(self, query, limit=3):
query = query.lower().strip()
results = []

for book in self.data:
score = 0
for keyword in book['keywords']:
if fuzz.partial_ratio(query, keyword) > 70: # Порог схожести
score += fuzz.partial_ratio(query, keyword)
if fuzz.partial_ratio(query, book['title'].lower()) > 70:
score += fuzz.partial_ratio(query, book['title'].lower())

if score > 0:
results.append({
'url': book['url'],
'title': book['title'],
'description': book['description'],
'score': score
})

return sorted(results, key=lambda x: x['score'], reverse=True)[:limit]

  • Класс BookSearch загружает JSON и ищет книги по запросу, используя fuzzywuzzy для нечеткого соответствия.

Шаг 4: Context Processor для передачи данных

Создайте shop/context_processors.py:

import os
from django.conf import settings
from shop.book_search import BookSearch

def book_search(request):
query = request.GET.get('s', '')
results = []

if query:
json_path = os.path.join(settings.BASE_DIR, 'books.json')
search_instance = BookSearch(json_path)
results = search_instance.search(query)

return {
'search_query': query,
'search_results': results,
}

Добавьте его в settings.py:

TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
...
'shop.context_processors.book_search',
],
},
},
]

Шаг 5: Шаблон с чат-ботом

Создайте templates/base.html:

<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Интернет-магазин книг</title>
<link rel="stylesheet" href="/static/css/styles.css">
</head>
<body>
<div class="site-wrapper">
{% block content %}{% endblock %}
</div>
</body>
</html>

Создайте templates/shop/home.html:

{% extends "base.html" %}
{% block content %}
<div class="atbs-search-full On">
<div id="search-dialog" class="dialog-box">
<div id="dialog-content" class="chat-container">
{% if search_results %}
<ul>
{% for result in search_results %}
<li><a href="{{ result.url }}">{{ result.title }}</a> - {{ result.description }}</li>
{% endfor %}
</ul>
{% elif search_query %}
<p>Ничего не найдено для "{{ search_query }}"</p>
{% else %}
<div class="message bot-message">
<p>Привет, любитель книг!</p>
<p>Напиши, какую книгу ищешь, и я помогу найти!</p>
</div>
{% endif %}
</div>
</div>

<form id="search-form" action="" method="get" onsubmit="return false;">
<input name="s" class="form-control" placeholder="Напиши, что ищешь..." type="text" value="">
<span id="atbs-search-remove"><i class="mdicon mdicon-close"></i></span>
</form>
</div>

<script>
const searchInput = document.querySelector('input[name="s"]');
const dialogBox = document.getElementById('search-dialog');
const dialogContent = document.getElementById('dialog-content');
const removeBtn = document.getElementById('atbs-search-remove');
const searchForm = document.getElementById('search-form');

window.addEventListener('load', function() {
dialogBox.style.display = 'block';
});

searchForm.addEventListener('submit', function(e) {
e.preventDefault();
const query = searchInput.value.trim();

if (query) {
const userMessage = document.createElement('div');
userMessage.classList.add('message', 'user-message');
userMessage.innerHTML = `<p>${query}</p>`;
dialogContent.appendChild(userMessage);

searchInput.value = '';

const url = new URL(window.location.href);
url.searchParams.set('s', query);

fetch(url, {
method: 'GET',
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
})
.then(response => {
if (!response.ok) throw new Error('Network response was not ok');
return response.text();
})
.then(html => {
const parser = new DOMParser();
const doc = parser.parseFromString(html, 'text/html');
const newDialogContent = doc.querySelector('#dialog-content');

const botMessage = document.createElement('div');
botMessage.classList.add('message', 'bot-message');

if (newDialogContent && newDialogContent.innerHTML.trim()) {
botMessage.innerHTML = newDialogContent.innerHTML;
} else {
botMessage.innerHTML = '<p>Ошибка: нет данных</p>';
}

dialogContent.appendChild(botMessage);
dialogBox.scrollTop = dialogBox.scrollHeight;
})
.catch(error => {
const errorMessage = document.createElement('div');
errorMessage.classList.add('message', 'bot-message');
errorMessage.innerHTML = '<p>Ошибка при поиске</p>';
dialogContent.appendChild(errorMessage);
dialogBox.scrollTop = dialogBox.scrollHeight;
});
}
});

removeBtn.addEventListener('click', function() {
searchInput.value = '';
dialogContent.innerHTML = `
<div class="message bot-message">
<p>Привет, любитель книг!</p>
<p>Напиши, какую книгу ищешь, и я помогу найти!</p>
</div>
`;
const url = new URL(window.location.href);
url.searchParams.delete('s');
window.history.pushState({}, document.title, url);
});
</script>
{% endblock %}

Шаг 6: Стилизация

Создайте static/css/styles.css:

.atbs-search-full {
background: rgba(0, 0, 0, 0.9);
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}

.dialog-box {
background: #fff;
padding: 20px;
border-radius: 5px;
max-width: 600px;
width: 100%;
max-height: 70vh;
overflow-y: auto;
}

.chat-container {
display: flex;
flex-direction: column;
gap: 10px;
}

.message {
padding: 10px;
border-radius: 5px;
max-width: 80%;
}

.bot-message {
background: #f0f0f0;
align-self: flex-start;
}

.user-message {
background: #d1e7dd;
align-self: flex-end;
text-align: right;
}

.form-control {
width: 600px;
padding: 10px;
font-size: 16px;
border: none;
border-radius: 5px;
margin-top: 20px;
}

#atbs-search-remove {
cursor: pointer;
margin-left: 10px;
color: #fff;
}

Подключите статику в settings.py:

STATIC_URL = '/static/'
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]

Шаг 7: View и URL

Создайте простую вьюху в shop/views.py:

from django.shortcuts import render

def home(request):
return render(request, 'shop/home.html')

Настройте urls.py:

# bookstore/urls.py
from django.urls import path
from shop.views import home

urlpatterns = [
path('', home, name='home'),
]

Шаг 8: Запуск

Установите зависимости

pip install fuzzywuzzy

Выполните миграции и запустите сервер:

python manage.py makemigrations
python manage.py migrate
python manage.py runserver

  1. Откройте http://127.0.0.1:8000/ и протестируйте бота:Введите "толстой" → бот предложит "Война и мир".
    Введите "python" → бот найдет "Программирование на Python".
    Введите "книга" → бот скажет "Ничего не найдено".

Итог

Вы создали простого чат-бота для интернет-магазина книг! Он работает без базы данных, использует JSON для хранения каталога и fuzzywuzzy для поиска с учетом опечаток. Этот подход легко масштабировать: добавьте больше книг в books.json или улучшите интерфейс, добавив кнопки или автодополнение.

Если у вас есть вопросы или идеи для улучшения, пишите в комментариях!