Django开发:跨视图获取房源Agent邮箱及多实例返回错误排查
问题描述
我用Django搭建网站,用户在property-detail页面(类视图)可联系对应房源的agent,填写表单后内容通过邮件发送给agent。邮件功能正常,但contact_agent是函数视图,无法动态获取对应房源的agent邮箱,同时出现报错:
MultipleObjectsReturned at /contact-agent/ get() returned more than one Property -- it returned 2
models.py
class Agent(models.Model): name = models.CharField(max_length=100) password = models.CharField(max_length=100) image = models.ImageField(upload_to = 'Images/') bio = models.TextField() instagram = models.URLField(max_length=100) twitter = models.URLField(max_length=100) facebook = models.URLField(max_length=100) linkedin = models.URLField(max_length=100) is_featured = models.BooleanField(default = False) slug = models.SlugField(default='') class Property(models.Model): price = models.IntegerField() price_per_sqft = models.IntegerField(null=True) address = models.CharField(max_length = 10000) state = models.CharField(max_length = 1000) country = models.CharField(max_length = 1000) description = models.TextField() image1 = models.ImageField(upload_to = 'Images/') image2 = models.ImageField(upload_to = 'Images/') image3 = models.ImageField(upload_to = 'Images/') agent = models.ForeignKey(Agent, on_delete=models.CASCADE) agent_description = models.TextField() is_featured = models.BooleanField(default = False) bedrooms = models.IntegerField() bathrooms = models.IntegerField() date_posted = models.DateTimeField(default=timezone.now) slug = models.SlugField(default='')
views.py
@login_required def contact_agent(request): property = get_object_or_404(Property) agent = property.agent if request.method == "POST": name = request.POST['name'] email = request.POST['email'] current_address = request.POST['current_address'] phone = request.POST['phone'] message = request.POST['message'] application = f"Name: {name}\nPhone: {phone}\nEmail: {email}\nCurrent Address: {current_address}\nMessage: {message}" email_message = EmailMessage( f'Message to agent {agent} from {name}', application, settings.EMAIL_HOST_USER, ['{agent.email}'], ) email_message.send() return render(request, 'users/contact_agent.html', { 'name': name, 'email': email, 'phone': phone, 'current_address': current_address, }) else: return render(request, 'blog/index.html', {})
问题总结
- 如何在函数视图
contact_agent中动态获取对应房源的agent邮箱 - 如何解决
get_object_or_404(Property)返回多个实例的错误
解决方案
1. 解决MultipleObjectsReturned错误
get_object_or_404(Property)未指定筛选条件,直接查询所有Property实例,当数据库存在多个房源时必然报错。必须通过房源的唯一标识(如slug或id)获取单个房源。
2. 动态获取对应房源的agent邮箱
需要从property-detail页面跳转时,传递房源的唯一标识给contact_agent视图,具体步骤如下:
步骤1:修改URL配置
给contact_agent的URL添加房源slug参数:
# urls.py from django.urls import path from . import views urlpatterns = [ # ...其他URL配置 path('contact-agent/<slug:property_slug>/', views.contact_agent, name='contact-agent'), ]
步骤2:修改property-detail页面的表单链接
在房源详情页的联系表单中,将action指向带房源slug的contact-agentURL:
<!-- property-detail.html 中的表单代码 --> <form action="{% url 'contact-agent' property.slug %}" method="POST"> {% csrf_token %} <!-- 表单字段:姓名、邮箱、电话等 --> <button type="submit">联系经纪人</button> </form>
步骤3:修改contact_agent视图
接收房源参数,获取对应房源和经纪人,同时修复邮件收件人格式错误:
@login_required def contact_agent(request, property_slug): # 通过slug获取单个房源,解决多实例错误 property = get_object_or_404(Property, slug=property_slug) agent = property.agent if request.method == "POST": name = request.POST['name'] email = request.POST['email'] current_address = request.POST['current_address'] phone = request.POST['phone'] message = request.POST['message'] application = f"Name: {name}\nPhone: {phone}\nEmail: {email}\nCurrent Address: {current_address}\nMessage: {message}" email_message = EmailMessage( f'Message to agent {agent.name} from {name}', application, settings.EMAIL_HOST_USER, [agent.email], # 修复:直接使用变量,无需字符串包裹 ) email_message.send() return render(request, 'users/contact_agent.html', { 'name': name, 'email': email, 'phone': phone, 'current_address': current_address, }) # GET请求时返回联系表单页面,传递房源和经纪人信息 return render(request, 'users/contact_agent.html', { 'property': property, 'agent': agent })
额外修复:Agent模型添加email字段
当前Agent模型缺少email字段,会导致agent.email报错,需补充字段:
# models.py class Agent(models.Model): # ...原有字段 email = models.EmailField(max_length=254, unique=True) # 添加邮箱字段
添加后执行迁移命令:
python manage.py makemigrations python manage.py migrate
内容的提问来源于stack exchange,提问作者Jack
相关产品推荐
相关产品推荐

