You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多对多关联下实现志愿者已报名活动展示与报名功能

Hey Chloe, let's walk through implementing these two key features for your volunteer activity tracking app. Since volunteers and activities have a many-to-many relationship, we'll start with solidifying the data model, then build out each feature step by step.

1. Database Setup (Many-to-Many Relationship)

First, you'll need three tables: one for volunteers, one for activities, and a junction table to handle the many-to-many links. Here's a SQL example:

-- Volunteers table to store volunteer details
CREATE TABLE volunteers (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100) NOT NULL,
    email VARCHAR(100) UNIQUE NOT NULL,
    -- Add other fields like phone number, skills, etc. as needed
);

-- Activities table to store event details
CREATE TABLE activities (
    id INT PRIMARY KEY AUTO_INCREMENT,
    title VARCHAR(200) NOT NULL,
    description TEXT,
    start_date DATETIME NOT NULL,
    end_date DATETIME NOT NULL,
    max_participants INT DEFAULT 0, -- Optional: Track activity capacity
    -- Add other fields like location, organizer, etc.
);

-- Junction table to link volunteers to their registered activities
CREATE TABLE volunteer_activity (
    volunteer_id INT NOT NULL,
    activity_id INT NOT NULL,
    PRIMARY KEY (volunteer_id, activity_id), -- Prevent duplicate registrations
    FOREIGN KEY (volunteer_id) REFERENCES volunteers(id) ON DELETE CASCADE,
    FOREIGN KEY (activity_id) REFERENCES activities(id) ON DELETE CASCADE
);
2. Feature 1: Volunteer Views Their Registered Activities

This requires fetching activities linked to the volunteer's ID via the junction table. Below are backend and frontend examples using Python/Flask and vanilla JavaScript.

Backend Endpoint (Flask + SQLAlchemy)

This endpoint returns all activities the volunteer has signed up for:

from flask import Flask, jsonify
from models import db, Volunteer, Activity, VolunteerActivity # Import your ORM models

@app.route('/volunteers/<int:volunteer_id>/registered-activities', methods=['GET'])
def get_registered_activities(volunteer_id):
    # Fetch activities by joining the junction table
    registered_activities = Activity.query.join(VolunteerActivity)\
        .filter(VolunteerActivity.volunteer_id == volunteer_id)\
        .all()
    
    # Convert to serializable format for frontend
    activity_data = []
    for activity in registered_activities:
        activity_data.append({
            'id': activity.id,
            'title': activity.title,
            'description': activity.description,
            'start_date': activity.start_date.strftime('%Y-%m-%d %H:%M'),
            'end_date': activity.end_date.strftime('%Y-%m-%d %H:%M')
        })
    
    return jsonify(activity_data)

Frontend Display

This code fetches and renders the volunteer's registered activities:

<div class="registered-activities-container">
    <h2>Your Registered Activities</h2>
    <ul id="activities-list"></ul>
</div>

<script>
// Get the authenticated volunteer's ID (use session/JWT in production)
const volunteerId = 123; // Replace with actual logged-in user ID

// Fetch and render activities when the page loads
function loadRegisteredActivities() {
    fetch(`/volunteers/${volunteerId}/registered-activities`)
        .then(res => res.json())
        .then(data => {
            const list = document.getElementById('activities-list');
            if (data.length === 0) {
                list.innerHTML = "<li>You haven't registered for any activities yet.</li>";
                return;
            }
            data.forEach(activity => {
                const li = document.createElement('li');
                li.innerHTML = `
                    <h3>${activity.title}</h3>
                    <p>${activity.description}</p>
                    <p><strong>Date:</strong> ${activity.start_date} to ${activity.end_date}</p>
                `;
                list.appendChild(li);
            });
        })
        .catch(err => console.error('Failed to load activities:', err));
}

window.onload = loadRegisteredActivities;
</script>
3. Feature 2: Volunteer Registers for a New Activity

This lets a volunteer click a button to add their ID to an activity's registration list. We'll include duplicate checks to avoid double-signups.

Backend Registration Endpoint

This endpoint handles the registration request securely:

@app.route('/activities/<int:activity_id>/register', methods=['POST'])
def register_for_activity(activity_id):
    # Get authenticated volunteer ID (use session/JWT in production)
    volunteer_id = 123; # Replace with actual logged-in user ID
    
    # Check if volunteer is already registered to avoid duplicates
    existing_reg = VolunteerActivity.query.filter_by(
        volunteer_id=volunteer_id,
        activity_id=activity_id
    ).first()
    
    if existing_reg:
        return jsonify({"message": "You're already registered for this activity!"}), 400
    
    # Create new registration entry
    new_reg = VolunteerActivity(volunteer_id=volunteer_id, activity_id=activity_id)
    db.session.add(new_reg)
    db.session.commit()
    
    return jsonify({"message": "Successfully registered for the activity!"}), 201

Frontend Registration Button

Add a "Register" button to each activity card that triggers the registration:

<!-- Example activity card -->
<div class="activity-card">
    <h3>Community Garden Planting Day</h3>
    <p>Help plant native flowers at the downtown garden on Sunday.</p>
    <p><strong>Date:</strong> 2024-05-19 10:00 to 14:00</p>
    <button onclick="registerForActivity(456)">Register Now</button>
</div>

<script>
function registerForActivity(activityId) {
    const volunteerId = 123; // Replace with authenticated user ID
    fetch(`/activities/${activityId}/register`, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            // Include CSRF token for security (required for most production apps)
            'X-CSRFToken': document.querySelector('meta[name="csrf-token"]').content
        }
    })
    .then(res => res.json())
    .then(data => {
        alert(data.message);
        // Refresh registered activities list after successful registration
        loadRegisteredActivities();
    })
    .catch(err => {
        console.error('Registration failed:', err);
        alert('Oops! Something went wrong. Please try again.');
    });
}
</script>
Key Notes to Keep in Mind
  • Authentication: Always verify the volunteer's identity using sessions, JWT, or another secure method—never trust client-side IDs alone.
  • Duplicate Prevention: The check for existing registrations in the backend is critical to avoid duplicate entries in the junction table.
  • Error Handling: Expand on the basic error handling to cover cases like invalid activity IDs, full capacity (if you track max participants), or database errors.
  • Validation: Add input validation for dates, email formats, etc., to keep your database clean.

内容的提问来源于stack exchange,提问作者Chloe Finn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:53:43