Как добавить 3 или более атрибутов модели в одно поле ManytoManyField в Django Models? Необходимо отобразить определенный итог во фронтенде
Постановка проблемы: Я хочу складывать атрибуты Activity
.models net_cost
изнутри Trip
.models, т.е. соединенные через ManytoManyField. У меня 3 или более вариантов на экземпляр, поэтому add:
из языка шаблонов недостаточно (https://docs.djangoproject.com/en/4.1/ref/templates/builtins/#add)
More Context: Activity связана с Trip
через ManytoManyField. Доступ и добавление через метод save
в models.py
вызывает ошибку id needs to be assigned first, я полагаю, так как ManytoMany может быть назначено только после сохранения экземпляра модели.
Даже если я обращаюсь ко всем им в views.py
перед рендерингом, переданный контекст даже после итерации по каждому объекту в списке может повторить только общий context["grand_total"]
для всех записей, отображаемых в шаблоне, тогда как мне нужен общий итог для каждого Trip
экземпляра во frontend List.view.
Модели:
Активность ->
class Activity(models.Model):
activity_location = [
...
]
acitivity_duration = [
...
]
activity_title = models.CharField(max_length=20, unique=True)
...
net_cost = models.PositiveIntegerField(validators=[MaxValueValidator(100000), MinValueValidator(0)], default=0)
class Meta:
ordering = ['-margin']
def __repr__(self):
return f"{self.activity_title} - {self.activity_location} - {self.net_cost}"
def __str__(self):
return f"Activity {self.activity_title}, Location {self.activity_location}, Duration {self.acitivity_duration}, Cost {self.net_cost}"
def get_absolute_url(self):
return reverse('activitys-list')
Поездка ->
class Trip(models.Model):
transfer_choices = [
...
]
transfers = models.CharField(max_length=11, choices=transfer_choices, blank=True, null=True)
activity = models.ManyToManyField(Activity, related_name="activities", blank=True, verbose_name='Activities', help_text='select multiple, note location tags')
....
class Meta:
ordering = ['-entry_created']
def __repr__(self):
return f'{self.customer.name} for {self.duration} day/s'
def __str__(self):
return f"{self.customer.name} - {self.duration} - {self.start_date} - {self.end_date}"
def save(self, *args, **kwargs):
...
#successfully processing all inhenrent model attributes for grand total, but
unable to process activity.net_cost for all entries.
super(Trip, self).save(*args, **kwargs)
def get_absolute_url(self):
return reverse('trip-lists')
Вид:
class TripLists(LoginRequiredMixin, ListView):
login_url = '/login/'
redirect_field_name = 'index'
model = Trip
template_name = 'gobasic/trip_list.html'
paginate_by = 10
def get_context_data(self, **kwargs):
# Call the base implementation first to get a context
context = super().get_context_data(**kwargs)
# Add in extra QuerySets here
Trips = Trip.objects.all()
activity_total = 0
for i in Trips:
for a in i.activity:
activity_total += a.net_cost
# Is pointless as same gets repeated.
context['activity_total'] = activity_total
context['total_trips'] = Trip.objects.all().count()
return context
Шаблон:
<h2>Trip List - {{total_trips}}</h2>
<p><a href="{% url 'trip-create' %} "><button type="button" class="btn btn-info">Add Trip</button></a>
<a href="{% url 'index' %}"> <button type="button" class="btn btn-info">Home</button>
</a></p>
<ol>
{% for t in object_list %}
<li><strong>🆔:</strong> {{ t.customer.name}}<strong> PB:</strong> {{ t.hotel_pb.hotel_name }} <strong>HV:</strong> {{ t.hotel_hv.hotel_name }} <strong>NL:</strong> {{ t.hotel_nl.hotel_name }} <!--<strong>Activities:</strong> {% for activity in t.activity.all %} {{ activity.activity_title}}, {% endfor %}--> <strong>Start:</strong>{{t.start_date.date}} <strong>End:</strong>{{t.end_date.date}} <strong>🏨:</strong>{{t.hotel_cost}} 🚕 {{t.transfer_cost}} | 🤿 {% for act in t.activity.all %} {{ act.net_cost}} {% endfor %}<strong> Grand Total= {{t.hotel_cost |add:t.transfer_cost}}</strong> <a href="{%url 'trip-update' t.pk%}"><button class="btn">🖋️</button></a> </li>
<br>
{% empty %}
<p>No Entries Detected Yet !</p>
{% endfor %}
</ol>
Как мне получить общую сумму, т.е. t.hotel_cost + t.transfer_cost + t.activity.net_cost (для всех объектов внутри деятельности, т.е. ManytoMany внутри object_list )