Reputation: 142
I created 2 models in the Django framework. The first model is responsible to save emails and the second model to save messages. All emails and messages are saved in the SQLite.db. But when I add the same emails multiple times, the data base creates a new record and I don't have a clue how can I manage saving data to retrieve multiple emails with the same name and then pass them as a one mutual email to the HTML template with all assigned messages to them.
An example: I sent 3 messages from [email protected]. Messages: ['Hi', 'Hello', 'Bonjour'] and one message from [email protected] ['Hi'] DB table:
Actual result: 3 records
Model:
class Email(models.Model):
"""The guest's email."""
text = models.EmailField(max_length=100)
date_added = models.DateTimeField(auto_now_add=True)
def __str__(self):
"""Return a string representation of the model."""
return self.text
class EmailMessage(models.Model):
"""The guest's message."""
email = models.ForeignKey(Email, on_delete=models.CASCADE)
message = models.TextField()
date_added = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.message
Then I want to pass all data to the HTML template in order to display them: url: /emails
def emails(request):
"""Show all emails."""
emails = Email.objects.order_by('date_added')
context = {'emails': emails}
return render(request, 'home/emails.html', context)
HTML portion: (I want to display only emails on this page, without messages, and when I click on each email, the user should be redirected to another page that display all messages assigned to a particular email.)
<h1>Emails</h1>
<ul>
{% for email in emails %}
<li>
<a href="{% url 'home:email' email.id %}">{{ email.text }}</a>
</li>
{% empty %}
<li>No emails have benn added yet.</li>
{% endfor %}
</ul>
url: /emails/email_id
def email(request, email_id):
"""Show a single email and all its messages."""
email = Email.objects.get(id=email_id)
messages = email.emailmessage_set.order_by('-date_added')
context = {'email': email, 'messages': messages}
return render(request, 'home/messages.html', context)
Template:
<h1>Email: {{ email }}</h1>
<ul>
{% for message in messages %}
<li>
<p>{{ message.date_added|date:'M d, Y H:i' }}</p>
<p>{{ message|linebreaks }}</p>
</li>
{% empty %}
<li>No emails have benn added yet.</li>
{% endfor %}
</ul>
But the final result is:
message_1: Hi
message_1: Hello
message_1: Bonjour
message_1: Hi
Expected result:
message_1: Hi
message_2: Hello
message_3: Bonjour
message_1: Hi
!!! Messages are available when I click on a particular email! So when User click on a particular email, he will be redirected to another page with all messages.
The question is how to handle it? And should I modify the HTML (javascript), view function or created models? Which approach is the best to make my page more stable?
Upvotes: 2
Views: 87
Reputation: 142
I added simple try-except block that solve this problem:
if form_email.is_valid() and form_message.is_valid():
try:
email = Email.objects.get(text=request.POST['text'])
except:
form_email.save()
email = Email.objects.last()
message = form_message.save(commit=False)
message.email = email
message.save()
Upvotes: 0
Reputation: 477210
We can pass the EmailMessage
s with:
def emails(request):
messages = EmailMessage.objects.select_related('email').order_by('date_added')
context = {'messages': messages}
return render(request, 'home/emails.html', context)
You can {% regroup … %}
[Django-doc] the messages by email address:
<h1>Emails</h1> <ul> {% regroup messages by email.text as message_group %} {% for email, messages in message_group %} <li> {{ email }}: <ul> {% for message in messages %} <a href="{% url 'home:email' message.pk %}">{{ message.message }}</a> {% endfor %} </ul> </li> {% empty %} <li>No emails have been added yet.</li> {% endfor %} </ul>
Upvotes: 1