xymind
xymind

Reputation: 33

filter articles for category in Dango

Very good, I am doing a personal blog as the first project in the world of web development, which I am developing with django, but I have a problem, the truth is I cannot find a way to filter my articles by categories, I show you my viewed models.

I have seen some examples using foreign keys but that causes me that the articles can only have a single category. I understand that to get the articles by categories I have to do a "fiilter" of categories but I even got there, if someone could guide me I would appreciate it very much

class Article(models.Model):
title = models.CharField(max_length=150, verbose_name='Titulo')
subtitle = models.CharField(max_length=50,default='Máximo 50 carácteres, que no se te olvide' ,verbose_name='subtitulo')
content = RichTextField(verbose_name="Contenido")
image = models.ImageField(default="null", verbose_name="Imagen", upload_to = "media")
user = models.ForeignKey(User, verbose_name="Usuario", on_delete=models.CASCADE, editable=False)
categories = models.ManyToManyField(Category, verbose_name="Categorias")
create_at = models.DateTimeField(auto_now_add=True, verbose_name="Creado el")
update_at = models.DateTimeField(auto_now=True, verbose_name="Editado el")

def __str__(self):
    return self.title

class Meta:
    verbose_name = ('Articulo')
    verbose_name_plural = ('Articulos')
    ordering = ['id']


class Category(models.Model):
name = models.CharField(max_length=100, verbose_name="Nombre")
description = models.CharField(max_length=255, verbose_name="Descripcion")
create_at = models.DateTimeField(auto_now_add=True, verbose_name="Creado el")

def __str__(self):
    return self.name

class Meta:
    verbose_name = ('Categoria')
    verbose_name_plural = ('Categorias')

/views:

def article(request, article_id):
    article = get_object_or_404(Article, id=article_id)
    articles = Article.objects.all()
    categorys = Category.objects.all()
    comments = Comentary.objects.filter(post = article_id)

Upvotes: 1

Views: 80

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477265

I have seen some examples using foreign keys but that causes me that the articles can only have a single category.

Indeed, by using a ManyToManyField [Django-doc], you can link an article to multiple categories, and a category can contain multiple articles.

Since you define first the Article, you can not refer to the Category later in the file, since at that moment Category is not defined yet. You can make use of a string literal to do this:

class Article(models.Model):
    # …
    categories = models.ManyToManyField('Category', verbose_name='Categorias')
    # …

class Category(models.Model):
    # …

Now we can retrieve the Categorys of a given Article with:

my_article.categories.all()

or we can obtain all Articles that at least have a given category with:

Article.objects.filter(categories=my_category)

If you want thus to render categories for the given article, you can work with:

def article(request, article_id):
    article = get_object_or_404(Article, id=article_id)
    articles = Article.objects.all()
    categorys = article.categories.all()
    comments = Comentary.objects.filter(post = article_id)

you can also make a view to see a Category with its related Articles with:

def category(request, category_id):
    category = get_object_or_404(Category, pk=category_id)
    articles = category.article_set.all()
    # …

Upvotes: 2

Related Questions