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

基于Django的会议文档Web应用自定义提醒模块开发问询

自定义会议提醒模块实现方案(Django + PostgreSQL + Ubuntu)

嘿,我之前刚好给一个Django会议管理系统做过类似的提醒模块,给你一步步拆解实现思路:

一、数据库模型设计

首先得把用户的个性化提醒规则存起来,关联到对应的会议和用户。我们可以新建一个Reminder模型,支持两种提醒方式:提前N分钟提醒或者自定义绝对时间提醒,同时记录提醒类型和发送状态:

# your_app/models.py
from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone
from .models import Meeting  # 假设你的会议模型是Meeting

class Reminder(models.Model):
    # 提醒方式选项(虽然不涉及发送,但先存类型)
    REMINDER_TYPES = (
        ('sms', '短信'),
        ('email', '邮件'),
        ('in_app', '站内通知'),
    )
    
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='meeting_reminders')
    meeting = models.ForeignKey(Meeting, on_delete=models.CASCADE, related_name='reminders')
    
    # 二选一:提前分钟数 或 绝对提醒时间
    offset_minutes = models.IntegerField(null=True, blank=True, help_text="提前多少分钟提醒,例如60=提前1小时")
    absolute_time = models.DateTimeField(null=True, blank=True, help_text="自定义具体提醒时间(如2018-04-25 19:30)")
    
    reminder_type = models.CharField(max_length=20, choices=REMINDER_TYPES)
    is_sent = models.BooleanField(default=False, help_text="是否已发送提醒")
    created_at = models.DateTimeField(auto_now_add=True)

    def get_trigger_time(self):
        """计算实际触发提醒的时间"""
        if self.absolute_time:
            return self.absolute_time
        elif self.offset_minutes:
            return self.meeting.start_time - timezone.timedelta(minutes=self.offset_minutes)
        return None

别忘了执行迁移:

python manage.py makemigrations
python manage.py migrate

二、定时任务触发提醒

因为提醒需要在指定时间自动触发,我们用Celery来处理定时任务(Ubuntu环境下非常适合),搭配Redis做消息队列。

1. 安装依赖

pip install celery redis

2. 配置Celery

在项目根目录新建celery.py:

# project_name/celery.py
import os
from celery import Celery

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project_name.settings')

app = Celery('project_name')
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks()

在project_name/__init__.py里添加:

from .celery import app as celery_app

__all__ = ('celery_app',)

3. 编写提醒检查任务

在你的app下新建tasks.py:

# your_app/tasks.py
from celery import shared_task
from django.utils import timezone
from django.db.models import F, Q
from .models import Reminder
from .utils import send_reminder  # 你自己实现的发送逻辑(无需关心具体发送方式)

@shared_task
def check_and_trigger_reminders():
    """每隔一段时间检查需要触发的提醒"""
    now = timezone.now()
    
    # 筛选出未发送且到了触发时间的提醒
    pending_reminders = Reminder.objects.filter(
        is_sent=False,
        Q(absolute_time__lte=now) |
        Q(
            offset_minutes__isnull=False,
            meeting__start_time__lte=now + timezone.timedelta(minutes=F('offset_minutes'))
        )
    )
    
    for reminder in pending_reminders:
        # 调用发送函数(你只需实现这个函数的逻辑,比如调用短信API/发邮件等)
        send_reminder(reminder)
        # 标记为已发送
        reminder.is_sent = True
        reminder.save()

4. 设置定时任务频率

在settings.py里配置Celery Beat(定时调度):

# settings.py
CELERY_BROKER_URL = 'redis://localhost:6379/0'
CELERY_RESULT_BACKEND = 'redis://localhost:6379/0'
CELERY_TIMEZONE = 'Asia/Shanghai'  # 改成你的时区

CELERY_BEAT_SCHEDULE = {
    'check-reminders-every-5-minutes': {
        'task': 'your_app.tasks.check_and_trigger_reminders',
        'schedule': 300.0,  # 每5分钟执行一次(单位:秒)
    },
}

三、用户界面:设置提醒的表单

给会议详情页添加一个表单,让用户可以设置个性化提醒:

1. 编写表单类

# your_app/forms.py
from django import forms
from .models import Reminder

class ReminderForm(forms.ModelForm):
    class Meta:
        model = Reminder
        fields = ['offset_minutes', 'absolute_time', 'reminder_type']
        widgets = {
            'absolute_time': forms.DateTimeInput(attrs={'type': 'datetime-local', 'class': 'form-control'}),
            'offset_minutes': forms.NumberInput(attrs={'class': 'form-control', 'placeholder': '输入提前分钟数'}),
            'reminder_type': forms.Select(attrs={'class': 'form-control'}),
        }

    def clean(self):
        """验证必须选一种提醒方式"""
        cleaned_data = super().clean()
        offset = cleaned_data.get('offset_minutes')
        absolute_time = cleaned_data.get('absolute_time')
        
        if not offset and not absolute_time:
            raise forms.ValidationError("请选择提前提醒时间或自定义提醒时间!")
        
        return cleaned_data

2. 视图集成表单

在会议详情视图里处理表单提交:

# your_app/views.py
from django.views.generic import DetailView
from django.contrib import messages
from .models import Meeting
from .forms import ReminderForm

class MeetingDetailView(DetailView):
    model = Meeting
    template_name = 'meeting/detail.html'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        # 把表单传入模板
        context['reminder_form'] = ReminderForm()
        return context

    def post(self, request, *args, **kwargs):
        self.object = self.get_object()
        form = ReminderForm(request.POST)
        
        if form.is_valid():
            reminder = form.save(commit=False)
            reminder.user = request.user
            reminder.meeting = self.object
            reminder.save()
            messages.success(request, "提醒设置成功!")
        
        return self.render_to_response(self.get_context_data(reminder_form=form))

3. 模板渲染表单

在会议详情模板里添加表单:

<!-- templates/meeting/detail.html -->
<h3>设置会议提醒</h3>
<form method="post" class="mt-3">
    {% csrf_token %}
    <div class="form-group">
        {{ reminder_form.offset_minutes.label_tag }}
        {{ reminder_form.offset_minutes }}
        <small class="form-text text-muted">例如:60 代表提前1小时提醒</small>
    </div>
    <div class="form-group">
        {{ reminder_form.absolute_time.label_tag }}
        {{ reminder_form.absolute_time }}
        <small class="form-text text-muted">或自定义具体提醒时间</small>
    </div>
    <div class="form-group">
        {{ reminder_form.reminder_type.label_tag }}
        {{ reminder_form.reminder_type }}
    </div>
    <button type="submit" class="btn btn-primary">保存提醒</button>
</form>

四、Ubuntu部署注意事项

因为你用Apache部署Django,Celery需要单独作为后台服务运行,我们用systemd配置:

  1. 创建/etc/systemd/system/celery.service文件:
[Unit]
Description=Celery Worker & Beat Service
After=network.target redis-server.service

[Service]
User=www-data
Group=www-data
WorkingDirectory=/path/to/your/django/project
Environment="PATH=/path/to/your/virtualenv/bin"
ExecStart=/path/to/your/virtualenv/bin/celery -A project_name worker --loglevel=info -B

[Install]
WantedBy=multi-user.target
  1. 启动并启用服务:
sudo systemctl daemon-reload
sudo systemctl start celery
sudo systemctl enable celery

这样Celery就会随系统启动,持续检查并触发提醒。

关键注意点

  • 时区问题:确保Django的settings.py里USE_TZ = True,并设置正确的TIME_ZONE,避免时间计算错误。
  • 重复提醒:模型里的is_sent字段一定要标记已发送,避免重复触发。
  • 容错处理:可以给Celery任务添加重试机制,避免因发送失败导致提醒丢失。

内容的提问来源于stack exchange,提问作者Adrian Chrostowski

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 04:02:15