So I am trying to build a website using Django where users can visit a property-detail
page then contact the property's agent
. Users need to fill out a form which will then be sent to the agent
via email. My email is working fine but since property-detail view
is a class-based view and the contact_agent view
is a function based view they are different views. So I can't seem to get the property's agent
dynamically to get the agent's
email to send him the email.
My 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='')
My 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', {})
The problem is that you likely got more than one Property
in the database. The line:
property = get_object_or_404(Property)
queries the database to return the Property
s, and if there is only one item, that is no problem. It will assign that one.
But the problem of course is when there are multiple Property
s. In that case, it thus can not be distinguished.
Likely this worked as long as there was one property. To disambiguate, you normally include the primary key in the path and thus query with that primary key:
@login_required
def contact_agent(request, pk):
property = get_object_or_404(Property, pk=pk)
# …
and in the path:
path('contact-agent/<int:pk>/', contact_agent)
and thus the view now is something like contact-agent/2/
where 2
is the primary key of the Property
for which you want to contact the agent.
Note: In case of a successful POST request, you should make a
redirect
[Django-doc] to implement the Post/Redirect/Get pattern [wiki]. This avoids that you make the same POST request when the user refreshes the browser.