如何在MongoDB中存储Django项目的注册用户数量?
Hey there! Since your other business data lives in MongoDB, integrating the Django user count there makes perfect sense. Let’s walk through the solution step by step, including whether you need a dedicated model.
Do You Need a Separate Model in models.py?
Short answer: It depends on how you want to interact with the data.
If you prefer using Django’s ORM for consistency (just like you would with your regular Django models), you can set up a model for MongoDB using a library like djongo (which lets Django ORM talk to MongoDB). Alternatively, you can directly use pymongo to interact with MongoDB without defining a Django model—this is more flexible if you already have existing MongoDB connections in your project.
Step-by-Step Implementation
1. Set Up MongoDB Connection
First, ensure your Django project can connect to MongoDB. Here are two common approaches:
Option A: Use djongo for ORM Integration
Install djongo first:
pip install djongo
Then add a MongoDB database entry in your settings.py (you can keep your default Django DB for auth/users, and add this as a second DB):
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', # or your existing auth DB 'NAME': BASE_DIR / 'db.sqlite3', }, 'mongodb': { 'ENGINE': 'djongo', 'NAME': 'your_business_db', # your existing business DB name 'CLIENT': { 'host': 'mongodb://localhost:27017/', # Add auth credentials if needed: 'username': 'your_user', 'password': 'your_pass' } } }
Option B: Direct pymongo Connection
If you already use pymongo for other business data, you can reuse that connection. For example:
from pymongo import MongoClient from django.conf import settings def get_mongo_db(): client = MongoClient(settings.MONGO_HOST, settings.MONGO_PORT) db = client[settings.MONGO_DB_NAME] # Authenticate if required: db.authenticate(settings.MONGO_USER, settings.MONGO_PASS) return db
Add the MongoDB config to settings.py:
MONGO_HOST = 'localhost' MONGO_PORT = 27017 MONGO_DB_NAME = 'your_business_db'
2. Store User Count in MongoDB
Now, let’s get the user count and save it to MongoDB.
If Using djongo Model
First, create a model in models.py:
from djongo import models from django.utils import timezone class UserStats(models.Model): stat_id = models.CharField(max_length=50, primary_key=True, default='user_count') total_users = models.IntegerField() updated_at = models.DateTimeField(default=timezone.now) class Meta: managed = True db_table = 'user_stats' app_label = 'your_app_name' # Replace with your app name
Then, to update the count (you can run this manually, via a signal, or a cron job):
from django.contrib.auth import get_user_model from your_app.models import UserStats User = get_user_model() user_count = User.objects.count() # Update or create the stats entry UserStats.objects.update_or_create( stat_id='user_count', defaults={'total_users': user_count, 'updated_at': timezone.now()} )
If Using Direct pymongo
Use this code to update the count:
from django.contrib.auth import get_user_model from your_app.utils import get_mongo_db # The function we defined earlier from datetime import datetime User = get_user_model() user_count = User.objects.count() db = get_mongo_db() stats_collection = db['user_stats'] # Upsert: update if exists, insert if not stats_collection.update_one( {'stat_id': 'user_count'}, {'$set': {'total_users': user_count, 'updated_at': datetime.now()}}, upsert=True )
3. Automate the Update
To avoid manually running the code every time a user is added/removed, use Django signals or a scheduled task:
Using Django Signals
Create a signals.py file in your app:
from django.db.models.signals import post_save, post_delete from django.contrib.auth import get_user_model from django.dispatch import receiver from datetime import datetime from your_app.utils import get_mongo_db # Or import your djongo model User = get_user_model() @receiver(post_save, sender=User) @receiver(post_delete, sender=User) def update_user_count_on_change(sender, instance, **kwargs): user_count = User.objects.count() db = get_mongo_db() stats_collection = db['user_stats'] stats_collection.update_one( {'stat_id': 'user_count'}, {'$set': {'total_users': user_count, 'updated_at': datetime.now()}}, upsert=True ) # If using djongo model: # UserStats.objects.update_or_create(stat_id='user_count', defaults={'total_users': user_count})
Then register the signal in your app’s apps.py:
from django.apps import AppConfig class YourAppConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' name = 'your_app_name' def ready(self): import your_app.signals
Using Scheduled Tasks (For High Traffic)
If you have a lot of user sign-ups/deletions, signals might add overhead. Instead, use a cron job or django-crontab to update the count periodically:
Install django-crontab:
pip install django-crontab
Add it to INSTALLED_APPS in settings.py, then define the cron job:
CRONJOBS = [ ('*/5 * * * *', 'your_app.tasks.update_user_count'), # Update every 5 minutes ]
Create a tasks.py file:
from django.contrib.auth import get_user_model from your_app.utils import get_mongo_db from datetime import datetime def update_user_count(): User = get_user_model() user_count = User.objects.count() db = get_mongo_db() stats_collection = db['user_stats'] stats_collection.update_one( {'stat_id': 'user_count'}, {'$set': {'total_users': user_count, 'updated_at': datetime.now()}}, upsert=True )
Final Notes
- Use Environment Variables: Store MongoDB credentials (host, port, username, password) in environment variables instead of hardcoding them for security.
- Custom User Model: If you’re using a custom user model, replace
get_user_model()with your model class wherever needed. - Performance: For very large user bases,
User.objects.count()can be slow. Consider using a cached value or database-specific optimizations (like PostgreSQL’scount(*)improvements if your auth DB is PostgreSQL).
内容的提问来源于stack exchange,提问作者Clister

