0

I'm making my portfolio site. Each project is developed with multiple technologies, such as a "website" created with Python, Django and Bootstrap.

So I defined my models like this:

class Technology(models.Model):
    name = models.CharField(max_length=50)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name_plural = 'Technologies'


class Project(models.Model):
    name = models.CharField(max_length=200)
    description = models.TextField()
    date = models.DateField()
    technology = models.ManyToManyField(Technology)
    image = models.ImageField(upload_to='projects')

    def __str__(self):
        return self.name

views.py:

def index(request):
    projects = Project.objects.all()
    return render(request, 'homepage/index.html', context={'projects': projects})

Now here's the challenge:

In my template I want to display 6 projects with the project name and technologies extracted from the '''queryobject'''. However right now I have only one project. So:

  1. How to display one set of HTML tags for first project and another set (placeholders) for the rest? So the first project shows the data from database, and the rest 5 show a "coming soon" (please refer to attached screenshot)? And later when I add the second and third projects to the database, the output update itself accordingly?
  2. Since the "technology" field is a manytomany field, there is more than one value in it (Python, Django, Bootstrap for example). How to access it in my template?

EDIT:

I feel I need to explain a little more. What I need for each project I have:

  1. Project Name
  2. First technology
  3. All technologies - This is needed for a javascript library I use to filter out projects based on technology. It looks like this:
<div class="col-lg-4 col-md-6 portfolio-item filter-python filter-django filter-bootstrap">

enter image description here

Omid Shojaee
  • 333
  • 1
  • 4
  • 20
  • what about, Project.objects.technology.all()? – Pdeuxa Jan 14 '21 at 14:15
  • I think this would make most sense to do this in the template. You could check the length of `projects` and if its less than 6 perhaps then you could add that coming soon place holder html. Have a look at the django documentation at the built in template tags - https://docs.djangoproject.com/en/3.1/ref/templates/builtins/#for. It should be pretty straight forward. – Grizzle Jan 14 '21 at 14:27
  • https://stackoverflow.com/questions/1107737/numeric-for-loop-in-django-templates this post may also be useful. – Grizzle Jan 14 '21 at 14:29
  • Will there be only 6 projects all the time ? – arjun Jan 14 '21 at 14:54

1 Answers1

0

For displaying the projects you have and a placeholder for the rest, you can do as follows in the view.

projects = Project.objects.all()
dummy_project_count = max(6 - projects.count(), 0)
dummy_loop_list = list(range(dummy_project_count))

pass this dummy_loop_list into the context and loop over it putting the placeholder in the template
For displaying all the technologies just loop over them in the template.

{% for technology in project.technology.all %}
Abdul Aziz Barkat
  • 19,475
  • 3
  • 20
  • 33
  • ```dummy_loop_list``` nicely solves the problem for placeholders, but what about the project I have? – Omid Shojaee Jan 14 '21 at 15:54
  • You can loop over projects – Abdul Aziz Barkat Jan 14 '21 at 15:55
  • Thanks. How do I access just one technology out of 3~4? Is there some sort of index or should I convert it to list and iterate it? – Omid Shojaee Jan 14 '21 at 19:15
  • You can loop over the technology as I said in the answer there's no need to convert to a list. – Abdul Aziz Barkat Jan 15 '21 at 05:51
  • Let me explain. In the homepage I want to display just one technology - the first one for example - this is what I'm asking. In the details page I'll loop over them to display all. – Omid Shojaee Jan 16 '21 at 15:34
  • `Technology.objects.all().first()` will return the first technology object or None if there are none. Order may be random so you might set an `order_by('field_name')` before calling `first()`. Just get this object and pass it in the context. – Abdul Aziz Barkat Jan 16 '21 at 15:39
  • ```{% for technology in project.technology.all %}``` returns AttributeError :( – Omid Shojaee Jan 22 '21 at 15:30
  • @OmidShojaee Can you elaborate? What is the error? – Abdul Aziz Barkat Jan 22 '21 at 15:32
  • ```AttributeError: 'QuerySet' object has no attribute 'technology``` Also I updated my post with some more details. – Omid Shojaee Jan 22 '21 at 16:46
  • You are trying to access it on the queryset i.e. you likely passed `Project.objects.all()` to the context as `project` and then are trying to access that, instead pass it as `projects` and then `{% for project in projects %}` loop and access. – Abdul Aziz Barkat Jan 22 '21 at 16:49
  • Looks like what I'm trying to do is not possible or I'm unable to explain it properly. Thank you so much for your time. – Omid Shojaee Jan 22 '21 at 17:44