Favoritenfunktion und Backend-Verwaltung

In diesem Kapitel lernst du, eine Lesezeichen-Funktion mithilfe von Viele-zu-viele-Beziehungen zu implementieren und mit Flask-Admin schnell eine Backend-Administration aufzubauen.


Entwurf von Viele-zu-viele-Beziehungen

Anforderungen an die Favoritenfunktion:Ein Benutzer kann mehrere Beiträge favorisieren, und ein Beitrag kann von mehreren Benutzern favorisiert werden.。

In SQLAlchemy werden Viele-zu-viele-Beziehungen mithilfe einerAssoziationstabelle-Implementierung umgesetzt.

Beispiel

# Dateipfad: models.py - Assoziationstabelle hinzufügen und das Post-Modell ändern
from datetime import datetime

# Assoziationstabelle: muss nicht als Modellklasse definiert werden, direkt mit db.Table erstellen
favorites = db.Table('favorites',
    db.Column('user_id', db.Integer, db.ForeignKey('users.id'), primary_key=True),
    db.Column('post_id', db.Integer, db.ForeignKey('posts.id'), primary_key=True),
    db.Column('created_at', db.DateTime, default=datetime.utcnow)
)

class Post(db.Model):
    __tablename__ = 'posts'
    # ... vorhandene Felder bleiben unverändert ...

Führen Sie dann die Migration aus:

(venv) $ flask db migrate -m "新增收藏关联表"
(venv) $ flask db upgrade

Ansichten zum Favorisieren und Entfavorisieren

Beispiel

# Dateipfad: app/blueprints/user.py (neue Datei)
from flask import Blueprint, render_template, redirect, url_for, request, flash
from flask_login import login_required, current_user
from app.models import Post, db, favorites

user_bp = Blueprint('user', __name__)

@user_bp.route("/favorite/<int:post_id>", methods=['POST'])
@login_required
def toggle_favorite(post_id):
    """Favoritenstatus umschalten"""
    post = Post.query.get_or_404(post_id)

    # Prüfen, ob bereits favorisiert: die Assoziationstabelle für diese Benutzer-Post-Kombination abfragen
    is_faved = db.session.query(favorites).filter(
        favorites.c.user_id == current_user.id,
        favorites.c.post_id == post.id
    ).first() is not None

    if is_faved:
        # Aus Favoriten entfernen
        db.session.execute(
            favorites.delete().where(
                (favorites.c.user_id == current_user.id) &
                (favorites.c.post_id == post.id)
            )
        )
        db.session.commit()
        flash(f'Aus Favoriten entfernt: "{post.title}"', 'info')
    else:
        # Favorit hinzufügen
        db.session.execute(
            favorites.insert().values(user_id=current_user.id, post_id=post.id)
        )
        db.session.commit()
        flash(f'Zu Favoriten hinzugefügt: "{post.title}"', 'success')

    return redirect(request.referrer or url_for('main.index'))


@user_bp.route("/favorites")
@login_required
def favorites_list():
    """Current user's favorites list"""
    # Artikel abfragen, die von Benutzern über die Assoziationstabelle favorisiert wurden
    faved_posts = Post.query.join(
        favorites, (favorites.c.post_id == Post.id)
    ).filter(
        favorites.c.user_id == current_user.id
    ).order_by(favorites.c.created_at.desc()).all()

    return render_template('favorites.html', posts=faved_posts)

Blueprint in app.py registrieren

Beispiel

from app.blueprints.user import user_bp
app.register_blueprint(user_bp)

Favoriten-Schaltflächen auf der Detailseite und der Listenseite hinzufügen

Beispiel

<!-- Im Bereich für Artikelaktionen von post_detail.html und index.html hinzufügen -->
{% if current_user.is_authenticated %}
<form method="post" action="{{ url_for('user.toggle_favorite', post_id=post.id) }}">
    <button type="submit" class="fav-btn">
        {% set is_faved = false %}
{# Prüfe, ob der aktuelle Benutzer in der Liste der Benutzer ist, die den Artikel favorisiert haben #}
♡ Favorit
    </button>
</Form>
{% endif %}

Lesezeichen-Operationen verwenden POST (Formularübermittlung), nicht GET-Links. GET-Anfragen sollten keine Seiteneffekte haben (Änderung der Datenbank); dies ist ein grundlegendes Prinzip der Webentwicklung.


Flask-Admin — Backend-Verwaltung

Flask-AdminEs ist die Erweiterung im Flask-Ökosystem, die Django Admin entspricht.

Nach der Konfiguration können Sie Artikel und Kategorien im.

(venv) $ pip install flask-admin

Beispiel

# Dateipfad: app.py oder erstellen Sie eine neue admin_setup.py
from flask_admin import Admin
from flask_admin.contrib.sqla import ModelView
from app.models import Post, Category, Benutzer

# Benutzerdefinierte ModelView: steuern, welche im Admin-Backend angezeigt werden
class PostAdmin(ModelView):
    column_list = ['title', 'category', 'created_at', 'updated_at']
    column_searchable_list = ['title', 'summary']
    column_filters = ['category', 'created_at']
    form_columns = ['title', 'slug', 'summary', 'content', 'category']

class CategoryAdmin(ModelView):
    column_list = ['name', 'slug']
    form_columns = ['name', 'slug']

# Admin-Instanz erstellen
admin = Admin(app, name='BEISPIEL Blog-Admin', template_mode='bootstrap4')
admin.add_view(PostAdmin(Post, db.session, name='Artikel'))
admin.add_view(CategoryAdmin(Category, db.session, name='Kategorien'))
admin.add_view(ModelView(User, db.session, name='Benutzer'))

Starten Sie den Server und besuchen Sie/admin, und Sie können die Admin-Oberfläche aufrufen.

Flask-Admin vs Django Admin

FunktionenFlask-AdminDjango Admin
IntegrationsmethodeDrittanbieter-Erweiterung, erfordert pip installIn django.contrib.admin integriert
Modelle registrierenadmin.add_view(ModelView(Model, session))admin.site.register(Model)
Listenfeldercolumn_listlist_display
Suchecolumn_searchable_listsearch_fields
Filtercolumn_filterslist_filter
Authentifizierung erforderlichNicht integriert (erfordert manuelles Hinzufügen von @login_required)Integrierte Administratorberechtigungen

Flask-Admin erfordert standardmäßig keine Anmeldung für den Zugriff; für die Berechtigungssteuerung muss es mit Flask-Login kombiniert werden. Eine einfache Möglichkeit ist es, hinzuzufügen@login_required, oder überschreiben Sie ModelView'sis_accessibleeine Methode zur Überprüfung von Administratorberechtigungen.


Kapitelzusammenfassung

In diesem Kapitel haben Sie zwei wichtige Funktionen implementiert: die Verwendung der Zuordnungstabelle db.Table + db.session.execute-Operationen, um die Viele-zu-viele-Beziehung für Lesezeichen umzusetzen; und die Verwendung von Flask-Admin, um schnell ein Backend-Verwaltungssystem aufzubauen.

Nun sind die interaktiven Funktionen des Blogs (Benutzer, Lesezeichen) und die Verwaltungsfunktionen (Backend) alle vollständig.

Weitere Erweiterungen