Загрузка данных
Вот обновленный код всех модулей без единого комментария, оформленный в строгом соответствии с вашими требованиями.
app.py
import os
import uuid
from werkzeug.utils import secure_filename
from flask import Flask, render_template, request, redirect, url_for, flash, abort
app = Flask(__name__)
app.secret_key = 'dev-key'
app.config['UPLOAD_FOLDER'] = 'static/uploads'
app.config['MAX_CONTENT_LENGTH'] = 2 * 1024 * 1024
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif', 'webp'}
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
def save_image(file):
if not file or file.filename == '':
return None
if not allowed_file(file.filename):
return None
ext = file.filename.rsplit('.', 1)[1].lower()
unique_name = f'{uuid.uuid4().hex}.{ext}'
path = os.path.join(app.config['UPLOAD_FOLDER'], unique_name)
os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)
file.save(path)
return unique_name
@app.route('/items/add', methods=['GET', 'POST'])
@login_required
def item_add():
if request.method == 'POST':
title = request.form.get('title', '').strip()
description = request.form.get('description', '').strip()
available = request.form.get('available') == 'on'
if not title:
flash('Введите название', 'error')
return redirect(url_for('item_add'))
file = request.files.get('image')
image_name = save_image(file)
if file and file.filename != '' and not image_name:
flash('Недопустимый формат файла', 'error')
return redirect(url_for('item_add'))
item = Item(
title=title,
description=description,
available=available,
image=image_name,
)
db.session.add(item)
db.session.commit()
files = request.files.getlist('images')
for f in files:
img_name = save_image(f)
if img_name:
db.session.add(Image(filename=img_name, item_id=item.id))
db.session.commit()
flash('Элемент успешно добавлен', 'success')
return redirect(url_for('item_list'))
return render_template('item_form.html', item=None)
@app.route('/items/<int:item_id>/edit', methods=['GET', 'POST'])
@login_required
@admin_required
def item_edit(item_id):
item = Item.query.get_or_404(item_id)
if request.method == 'POST':
title = request.form.get('title', '').strip()
description = request.form.get('description', '').strip()
available = request.form.get('available') == 'on'
if not title:
flash('Введите название', 'error')
return redirect(url_for('item_edit', item_id=item.id))
new_image = save_image(request.files.get('image'))
if new_image:
if item.image:
old_path = os.path.join(app.config['UPLOAD_FOLDER'], item.image)
if os.path.exists(old_path):
os.remove(old_path)
item.image = new_image
item.title = title
item.description = description
item.available = available
files = request.files.getlist('images')
for f in files:
img_name = save_image(f)
if img_name:
db.session.add(Image(filename=img_name, item_id=item.id))
db.session.commit()
flash('Элемент обновлён', 'success')
return redirect(url_for('item_detail', item_id=item.id))
return render_template('item_form.html', item=item)
@app.route('/items/<int:item_id>/delete', methods=['POST'])
@login_required
@admin_required
def item_delete(item_id):
item = Item.query.get_or_404(item_id)
if item.image:
path = os.path.join(app.config['UPLOAD_FOLDER'], item.image)
if os.path.exists(path):
os.remove(path)
for img in item.images:
path = os.path.join(app.config['UPLOAD_FOLDER'], img.filename)
if os.path.exists(path):
os.remove(path)
db.session.delete(item)
db.session.commit()
flash('Элемент удалён', 'success')
return redirect(url_for('item_list'))
@app.errorhandler(413)
def too_large(error):
flash('Файл слишком большой (максимум 2 МБ)', 'error')
return redirect(request.url)
models.py
class Item(db.Model):
__tablename__ = 'items'
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(150), nullable=False)
description = db.Column(db.Text, nullable=True)
available = db.Column(db.Boolean, default=True)
image = db.Column(db.String(200), nullable=True)
images = db.relationship('Image', backref='item', cascade='all, delete-orphan')
class Image(db.Model):
__tablename__ = 'images'
id = db.Column(db.Integer, primary_key=True)
filename = db.Column(db.String(200), nullable=False)
item_id = db.Column(db.Integer, db.ForeignKey('items.id'), nullable=False)
static/style.css
.thumb {
width: 60px;
height: 60px;
object-fit: cover;
border-radius: 6px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.no-image {
color: #888;
font-style: italic;
}
.detail-image {
max-width: 100%;
max-height: 400px;
border-radius: 8px;
object-fit: contain;
margin-bottom: 20px;
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
}
.gallery {
display: flex;
flex-wrap: wrap;
gap: 12px;
margin-top: 15px;
}
.gallery-item {
width: 100px;
height: 100px;
object-fit: cover;
border-radius: 6px;
transition: transform 0.2s ease;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}
.gallery-item:hover {
transform: scale(1.03);
}