Django模型字段周期性更新方案咨询(不限线程实现)
Hey there! Let's break down your problem step by step—there are a few key pieces you might have missed that are keeping your current approach from working.
First: Fix the status property issue
Right now, your status is a Python property—this means it only exists in memory for the current Feed object instance, not in the database. Any changes you make via self.set_status() will disappear as soon as that instance is discarded (like when the thread finishes).
If you need status changes to persist and be visible to users, you should convert it to a proper database field first:
class Feed(models.Model): name = models.ForeignKey(Name, on_delete=models.CASCADE, default=0) source = models.ForeignKey(Source, on_delete=models.CASCADE, default=0) status = models.CharField(max_length=20, default='ACTIVE') # 👈 Make this a DB field def set_status(self, _status=None): if _status is None: self.status = 'ACTIVE' else: self.status = _status self.save() # 👈 Save changes to the database!
This way, updates to status are stored permanently and will show up in future requests.
Second: Get your periodic task working (without Celery)
You mentioned trying Django-Q and it not working—let's fix that first, since it's a great lightweight alternative to Celery. The problem with your current code is that you're calling schedule() directly in admin.py, which only runs once when the admin module loads, not as part of Django-Q's task execution pipeline. Here's the correct approach:
- Verify Django-Q configuration in
settings.py:
INSTALLED_APPS = [ # ... your other apps 'django_q', ] Q_CLUSTER = { 'name': 'DjangORM', 'workers': 4, 'timeout': 90, 'retry': 120, 'queue_limit': 50, 'bulk': 10, 'orm': 'default' }
- Create a management command to schedule the task (instead of putting it in
admin.py). Createmanagement/commands/schedule_status_updates.py:
from django.core.management.base import BaseCommand from django_q.tasks import schedule from django.utils import timezone from myapp.models import Feed # Replace 'myapp' with your actual app name class Command(BaseCommand): help = 'Schedules periodic status updates for Feed objects' def handle(self, *args, **options): # Delete existing schedules for this task to avoid duplicates from django_q.models import Schedule Schedule.objects.filter(func='myapp.models.Feed.set_status').delete() # Schedule the task to run every 1 minute schedule( 'myapp.models.Feed.set_status', 'not active', schedule_type='I', minutes=1, repeats=-1, next_run=timezone.now() ) self.stdout.write(self.style.SUCCESS('Successfully scheduled status update task'))
- Run the command once to set up the schedule:
python manage.py schedule_status_updates
- Start the Django-Q cluster (this is the step you probably missed—Django-Q needs a running cluster to execute tasks):
python manage.py qcluster
Now your set_status method should be called every minute as expected.
If you don't want to use Django-Q, another lightweight option is APScheduler with the django-apscheduler package—install it, add it to your apps, and define a scheduled job that iterates over Feed objects to update their status.
Third: Refresh the page to show updated status
Once your status is updating in the database, you need to make sure users see changes without manual refreshes. You have two solid options:
- Frontend polling: Use JavaScript to periodically fetch the latest status from an API endpoint. Example:
// In your template's script tag setInterval(() => { fetch(`/api/feed-status/{{ feed.id }}/`) .then(response => response.json()) .then(data => { document.getElementById('feed-status').textContent = data.status; }); }, 60000); // Refresh every 60 seconds
You'll need to create a simple Django view that returns the Feed's status as JSON.
- Real-time updates with Django Channels: For instant updates (no waiting for polling intervals), use Django Channels to set up WebSockets. Whenever a Feed's status is updated, send a message to connected clients, and the frontend can update the UI immediately.
Quick Recap
- Convert
statusto a database field so changes persist - Set up a lightweight periodic task runner (Django-Q or APScheduler) correctly, and make sure the task runner is running
- Add frontend polling or WebSockets to update the UI automatically
内容的提问来源于stack exchange,提问作者Flora Biletsiou

