Home > Mobile >  Filtering tagged blog posts using intermediate table in Django
Filtering tagged blog posts using intermediate table in Django

Time:10-30

I am trying to render a page by filtering the articles by tags. I want the related articles to be displayed when a user clicks the tag in All-articles.html

Im not sure how to go about it or how I would write the code.

Should I create a path in urls.py like path('tag/<str:tagslug>', views.tag, name='tag'), so that I can access the url within the views.py?

How would I write the ORM to filter articles by tags in views.py?

Any help will be appreciated :) Thanks

models.py

class ArticleTags(models.Model):
    article = models.ForeignKey('Articles', models.DO_NOTHING)
    tag = models.ForeignKey('Tags', models.DO_NOTHING)

class Tags(models.Model):
    tag = models.CharField(unique=True, max_length=75)
    tagslug = models.SlugField(max_length=200, unique=True, default=None)

class Articles(models.Model):
    title = models.CharField(max_length=155)
    metatitle = models.CharField(max_length=155)
    slug = models.SlugField(unique=True, max_length=155)
    summary = models.TextField(blank=True, null=True)
    field_created = models.DateTimeField(db_column='_created', blank=True, null=True)  
    cover = models.ImageField(upload_to="cover", blank=True, default='logo-00-06.png')

views.py

def allarticles(request):
    articles_list = Articles.objects.all()
    paginator = Paginator(articles_list, 12)

    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)

    context = {'page_obj': page_obj}
    return render(request, "All-articles.html", context)

All-articles.html

{% for article in page_obj %}
    <article>
      <div>
        <img
          src="media/{{ article.cover }}"
          alt="menu item"
          class="article-photo"
        />
      </div>
      <header>
        <h4>{{ article.title }}</h4>
      </header>
    </article>
{% endfor %}

CodePudding user response:

You could begin by setting it up so when the user clicks the tag, it sends the tag name to the server via POST request. You could then filter the articles via the tag name and return the new context to the template.

The problem with this is you will have a page refresh unless you do it via AJAX or use e.preventdefault()

If you're going to have multiple actions on one page that requires HTTP requests, I would strongly recommend avoiding page refreshes.

When the user selects a tag, make an Ajax request like so:

All-Articles.js

function myAjaxRequest() {
    return $.ajax({
        type: 'POST',
        url: 'your route to the function in views.py (if its the same page, this 
        will be an empty string)',
        data: {filter: yourTag}
    })
}

Then use the tag to filter your data and return via Json Response.

views.py


def allarticles(request):
    if request.is_ajax():
       tag = request.POST['filter']
       *Now just use the tag to filter your model.*
       data = serializers.serialize('json', MyModel.objects.filter(field_name=tag))
       return JsonResponse(data, safe=False)

Finally, take the response and insert it into your HTML where it belongs. You will get the response from the return of your AJAX call in your Javascript file.

  • Related