Как отобразить набор тегов в шаблоне django

Я пытаюсь вывести теги из отношения "многие ко многим", но мне чего-то не хватает

Вот мои модели:

class Post(models.Model):
    date = models.DateTimeField(auto_now_add=True)
    author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name='posts', null=True, blank=True)
    title = models.CharField(max_length=200)
    content = models.TextField(null=True, blank=True)
    image = models.ImageField(upload_to='post/images/', null=True, blank=True)
    slug = models.SlugField(max_length=200, unique=True, null=True, blank=True)
    tag = models.ManyToManyField('Tag', related_name='posts', blank=True)

    def save(self, *args, **kwargs):
        if self.image:
            ext = os.path.splitext(self.image.name)[1]
            filename = f"{datetime.now().strftime('%Y%m%d%H%M%S')}{ext}"
            self.image.name = filename
        if not self.slug:
            self.slug = slugify(self.title)
        return super().save(*args, **kwargs)

class Tag(models.Model):
    name = models.CharField(max_length=200)
    slug = models.SlugField(max_length=200, unique=True, blank=True)
    post = models.ManyToManyField(Post, related_name='tags', blank=True)


    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.name)
        return super().save(*args, **kwargs)

    def __str__(self):
        return self.name

Это мой фрагмент шаблона

    {% for post in posts  %}
        <div class="news-card">
         
          <img src="{{post.image.url}}" class="news-img" alt="News" />
          <div class="news-listing">
          <ul class="tags">
             {% for tag in post.tag.all %}
              <li class="tag">{{tag.name}}</li>
              {% endfor %} 
            </ul>
            <h3 class="news-title">
              <a href="{{post.slug}}"
                >{{post.title}}</a

это мой вид и контекст, который я передаю

form = MessageForm()
        context = {
        'posts': posts,
        'events': events,
        'introductorys': introductory,
        'products': products,
        'form': form,
        'authors': 'authors',
    }
        return render(request, 'app/index.html', context)

Я ожидаю, что будет сгенерирован список тегов, но шаблон не генерирует никаких тегов

Вы дублируете теги ManyToManyField: вы делаете один в первой модели и один во второй. Это означает, что таким образом существуют два отношения, и добавление Post к одному тегу не приведет к появлению второго.

You thus should merge the two ManyToManyFields in one. It is not necessary to make a second one: with related_name=… [Django-doc] you add a descriptor in the other to access the objects in the opposite way.

Например, мы можем использовать:

class Post(models.Model):
    def post_image_filename(self, filename):
        ext = os.path.splitext(self.image.name)[1]
        filename = f"post/images/{datetime.now().strftime('%Y%m%d%H%M%S')}{ext}"

    date = models.DateTimeField(auto_now_add=True)
    author = models.ForeignKey(
        Author,
        on_delete=models.CASCADE,
        related_name='posts',
        null=True,
        blank=True,
    )
    title = models.CharField(max_length=200)
    content = models.TextField(null=True, blank=True)
    image = models.ImageField(
        upload_to=post_image_filename, null=True, blank=True
    )
    slug = models.SlugField(max_length=200, unique=True, null=True, blank=True)
    tags = models.ManyToManyField('Tag', related_name='posts', blank=True)

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.title)
        return super().save(*args, **kwargs)


class Tag(models.Model):
    name = models.CharField(max_length=200)
    slug = models.SlugField(max_length=200, unique=True, blank=True)
    # no post

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.name)
        return super().save(*args, **kwargs)

    def __str__(self):
        return self.name

Таким образом, мы работаем с:

<ul class="tags">
  {% for tag in post.tags.all %}
    <li class="tag">{{ tag.name }}</li>
  {% endfor %} 
</ul>

Note: You can make use of django-autoslug [GitHub] to automatically create a slug based on other field(s).

Вернуться на верх