Django & SQLite.db - данные дублируются

Я создал 2 модели во фреймворке Django. Первая модель отвечает за сохранение писем, а вторая - за сохранение сообщений. Все письма и сообщения сохраняются в SQLite.db. Но когда я добавляю одни и те же письма несколько раз, база данных создает новую запись, и я не знаю, как я могу управлять сохранением данных, чтобы получить несколько писем с одинаковым именем и затем передать их как одно взаимное письмо в HTML шаблон со всеми назначенными им сообщениями

Пример: Я отправил 3 сообщения с сайта test@test.com. Сообщения: ['Hi', 'Hello', 'Bonjour'] и одно сообщение с user@user.com ['Hi']. Таблица БД:

Фактический результат: 3 записи

  1. test@test.com | 'Hi'
  2. test@test.com | 'Hello'
  3. test@test.com | 'Bonjour'
  4. user@user.com | 'Hi'

Модель:

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

Затем я хочу передать все данные в шаблон HTML, чтобы отобразить их:

def emails(request):
    """Show all emails."""
    emails = Email.objects.order_by('date_added')
    context = {'emails': emails}
    return render(request, 'home/emails.html', context)

HTML-часть:

<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>

Но конечный результат таков:

  1. test@test.com

сообщение_1: Привет

  1. test@test.com

message_1: Hello

  1. test@test.com

message_1: Bonjour

  1. user@user.com

сообщение_1: Привет

Ожидаемый результат:

  1. test@test.com

сообщение_1: Привет

message_2: Hello

сообщение_3: Bonjour

  1. user@user.com

сообщение_1: Привет

Вопрос в томкак с этим справиться? И должен ли я модифицировать HTML (javascript), функцию просмотра или созданные модели ? Какой подход лучше всего подходит для того, чтобы сделать мою страницу более стабильной?

Чтобы сгруппировать сообщения по электронной почте, вам нужно изменить функцию представления, чтобы сгруппировать сообщения на основе электронной почты. Вот пример кода для вашей функции представления:

def emails(request):
    """ Show all emails with grouped messages."""
    emails = Email.objects.order_by('date_added').values('email').annotate(message_count=Count('email'))
    messages = Message.objects.order_by('email') # guessing that you message is saved in this model.
    context = {'emails': emails, 'messages': messages}
    return render(request, 'home/emails.html', context)

#html файл

<h1>Emails</h1>
    
    <ul>
        {% for email in emails %}
            <li>{{ email.email }}</li>
            <ul>
                {% for message in messages %}
                    {% if email.email == message.email %}
                        <li>message_{{ forloop.counter }}: {{ message.text }}</li>
                    {% endif %}
                {% endfor %}
            </ul>
        {% empty %}
            <li>No emails have been added yet.</li>
        {% endfor %}
    </ul>

Мы можем передать EmailMessageс помощью:

def emails(request):
    messages = EmailMessage.objects.select_related('email').order_by('date_added')
    context = {'messages': messages}
    return render(request, 'home/emails.html', context)

Вы можете {% regroup … %} [Django-doc] сообщения по адресу электронной почты:

<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>

Я добавил простой блок try-except, который решает эту проблему:

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()
Вернуться на верх