0

I am learning Django by building an application, called TravelBuddies. It will allow travelers to plan their trip and keep associated travel items (such as bookings, tickets, copy of passport, insurance information, etc), as well as create alerts for daily activities. The application will also able to update local information such as weather or daily news to the traveler. Travelers can also share the travel information with someone or have someone to collaborate with them to plan for the trip.

I am facing a problem. When I go to http://127.0.0.1:8000/triplist/, I see this page: enter image description here

When I click on Trip Name: Kuala Lumpur and taken to activity.html through this link: http://127.0.0.1:8000/triplist/kuala-lumpur/: enter image description here

"john" and "williams" are two separate user names. They need to be separated by a comma (,). So it will look like this: Co-traveller: john, williams. How can I do it?

Here are my codes in models.py:

from django.contrib.auth.models import User
from django.db import models
from django.template.defaultfilters import slugify

# Create your models here.

class Trip(models.Model):
    trip_name = models.CharField(max_length=100)
    date = models.DateField()
    planner_name = models.CharField(max_length=100)
    add_coplanner = models.ManyToManyField(User)
    slug = models.SlugField(max_length=150, default='null')

    def __str__(self):
        return self.trip_name

    def save(self, *args, **kwargs):
        self.slug = slugify(self.trip_name)
        super().save(*args, **kwargs)

class Activity(models.Model):
    trip = models.ForeignKey(Trip, on_delete=models.CASCADE)
    activity_name = models.CharField(max_length=100)
    date = models.DateField(auto_now=True)
    time = models.TimeField(auto_now= True)
    location = models.CharField(max_length=100)
    item_type = models.CharField(max_length=100)
    item_number = models.CharField(max_length=100)
    add_cotraveller = models.ManyToManyField(User)
    slug = models.SlugField(max_length=150, default='null')


    def __str__(self):
        return self.activity_name

    def save(self):
        super(Activity, self).save()
        self.slug = '%i-%s' % (
            self.id, slugify(self.trip.trip_name)
        )
        super(Activity, self).save()

Here are my codes in views.py:

from django.views import generic
from .models import Trip, Activity


class TripListView(generic.ListView):
    template_name = 'trips/triplist.html'
    context_object_name = 'all_trips'

    def get_queryset(self):
        return Trip.objects.all()


class ActivityView(generic.DetailView):
    model = Trip
    template_name = 'trips/activity.html'

Here are my codes in urls.py:

from . import views
from django.urls import path

app_name = 'trips'

urlpatterns = [
    path('triplist/', views.TripListView.as_view(), name='triplist'),
    path('triplist/<slug:slug>/', views.ActivityView.as_view(), name='activity'),
]

Here are my codes in apps.py:

from django.apps import AppConfig


class TripsConfig(AppConfig):
    name = 'trips'

Here are my codes in triplist.html:

<!DOCTYPE html>
{% extends 'trips/base.html' %}
{% load static %}
<html lang="en">
<link rel="stylesheet" type="text/css" href="{% static "css/style.css" %}">

<head>
    <meta charset="UTF-8">
    {% block title%}Trip list{% endblock %}
    <title>Trip list</title>
</head>


<body>
    {% block content %}
    <!--Page content-->
    <h1>This is Trip List Page</h1>


    <ol>
        {% for trip in all_trips %}
        <ol>
            <li><a href="{% url 'trips:activity' trip.slug %}">Trip name: {{ trip.trip_name }}</a></li>
            Date: {{ trip.date }}<br>
            Planner: {{ trip.planner_name }}<br>
            Coplanners:
                {% for user in trip.add_coplanner.all %}
                    {{user.username}}
                {% endfor %}<br>
<!--            Co-planner: {{ trip.add_coplanner.all }}<br>-->
        </ol>
        {% endfor %}


    </ol>

    <img src="{% static "images/botanical-garden.jpg" %}" alt="Botanical Garden" />
    <!-- New line -->
    {% endblock %}
</body>
</html>

Here are my codes in activity.html:

{% extends 'trips/base.html' %}
{% block title%}
Detail
{% endblock %}


{% block content %}

<h3>Activities for {{trip.trip_name}} </h3>

{% for trip_item in trip.activity_set.all %}
<!--<p>Activity name: {{ trip_item.activity_name }}</p>-->
<ol>
    <li>Activity name: {{ trip_item.activity_name }}</li>
    Date: {{ trip_item.date }}<br>
    Time: {{ trip_item.time }}<br>
    Location: {{ trip_item.location }}<br>
    Item Type: {{ trip_item.item_type }}<br>
    Item No: {{ trip_item.item_number }}<br>
    Co-traveller:
                {% for user in trip_item.add_cotraveller.all %}
                    {{user.username}}
                {% endfor %}<br>
<!--    Co-traveller: {{ trip_item.add_cotraveller.all }}-->
</ol>
{% endfor %}

{% endblock %}

Do I have to make any change in models.py?

Shawn
  • 173
  • 14

3 Answers3

2
Co-traveller:
                {% for user in trip_item.add_cotraveller.all %}
                    {% if forloop.last %}
                    {{user.username}}
                    {% else %}
                     {{user.username}} , 
                    {% endif %}
                {% endfor %}<br>

you can use this. do give a space after ,

arjun
  • 7,230
  • 4
  • 12
  • 29
Exprator
  • 26,992
  • 6
  • 47
  • 59
  • I add your codes. But I get this error `TemplateSyntaxError at /triplist/kuala-lumpur/ Invalid block tag on line 31: 'endblock', expected 'empty' or 'endfor'. Did you forget to register or load this tag?` – Shawn Dec 05 '19 at 06:37
  • which one is line 31?? i dont think any problem is here – Exprator Dec 05 '19 at 06:40
  • This time, it works with these codes: `Co-traveller: {% for user in trip_item.add_cotraveller.all %} {% if forloop.last %} {{user.username}} {% else %} {{user.username}}, {% endif %} {% endfor %}
    `
    – Shawn Dec 05 '19 at 06:42
  • Would you please take a look at this question? I am facing a new problem. https://stackoverflow.com/questions/59223347/django-getting-noreversematch-while-submitting-the-form-url-has-slug – Shawn Dec 07 '19 at 05:53
1

You can separate user with comma like this:

        Co-traveller:
            {% for user in trip_item.add_cotraveller.all %}
                {{user.username}}{% if not forloop.last %}, {% endif %}
            {% endfor %}<br>
arjun
  • 7,230
  • 4
  • 12
  • 29
  • I am facing problem with `activity.html`, not with `triplist.html`. Would you please take a look at these codes in `activity.html`? `Co-traveller: {% for user in trip_item.add_cotraveller.all %} {{user.username}} {% endfor %}
    `
    – Shawn Dec 05 '19 at 06:39
  • @Shawn you can do the same with this.updated my answer – arjun Dec 05 '19 at 06:41
0

One more way is to create a instance method and return a string from your model. For eg.

class Activity(models.Model):
    #fields
    add_cotraveller = models.ManyToManyField(User)

    def __str__(self):
        return self.activity_name

    def get_cotravellers(self):
        return ", ".join(u.username for u in self.add_coplanner.all())

and in template you can access it like:

Coplanners: {{ trip_item.get_cotravellers }}
Nalin Dobhal
  • 2,292
  • 2
  • 10
  • 20