Django视图处理短信:排查号码校验与Contacts对象创建异常
Hey there, let's walk through the issues in your code and fix them step by step.
Key Problems in Your Current Code
1. Broken QuerySet Iteration
You wrapped Contacts.objects.all() in a list with subscribers = [Contacts.objects.all()] — this means when you loop through subscribers, you're not iterating over individual contact objects, but instead looping over a single item that's the entire QuerySet. This completely breaks the comparison logic inside your loop.
2. Flawed Existence Check Logic
Right now, your loop will create a new Contacts object every time it encounters a contact that doesn't match the incoming number. If you have 5 existing contacts and the new number isn't any of them, you'll end up creating 5 duplicate entries for the same number. Even worse, if the number does exist, you'll send the "How old are you?" message multiple times (once for every existing contact).
3. Missing Uniqueness Enforcement in the Database
Your customer_number field doesn't have a unique=True constraint. This means the database won't block duplicate entries for the same phone number, which goes against your core requirement of one Contacts object per sender.
Fixed Code
models.py
Add unique=True to enforce one entry per phone number at the database level:
from django.db import models class Contacts(models.Model): customer_number = models.CharField(max_length=15, unique=True) customer_age = models.CharField(max_length=4, null=True) customer_income = models.CharField(max_length=10, null=True) def __unicode__(self): return self.customer_number
views.py
Use Django's built-in get_or_create method (clean, safe, and atomic) to handle the existence check and creation in one step:
from django.http import request from django_twilio.decorators import twilio_view from django_twilio.request import decompose from twilio.twiml.messaging_response import MessagingResponse from .models import Contacts @twilio_view def sms_choice(request): twilio_request = decompose(request) contact_num = twilio_request.from_ contact_info = ['Thanks for your subscription', "How old are you?", "Annual Income?"] response = twilio_request.body resp = MessagingResponse() # Atomic check: get existing contact or create a new one contact, created = Contacts.objects.get_or_create(customer_number=contact_num) if created: # New subscriber, send welcome message resp.message(contact_info[0]) else: # Returning subscriber, send next question resp.message(contact_info[1]) print(contact_num, response) return str(resp)
Why This Works
get_or_createis an atomic operation, so it eliminates race conditions (no chance of duplicate entries even if two requests for the same number hit your server at the same time).- We've removed the inefficient loop over all contacts, which will scale much better as your database grows.
- The
unique=Trueconstraint adds an extra layer of protection to ensure your data stays consistent.
内容的提问来源于stack exchange,提问作者Ach1916

