【问题标题】:Filtering tagged blog posts using intermediate table in Django使用 Django 中的中间表过滤标记的博客文章
【发布时间】:2021-12-14 06:04:49
【问题描述】:

我正在尝试通过按标签过滤文章来呈现页面。我希望在用户单击 All-articles.html 中的标签时显示相关文章

我不知道该怎么做,也不知道如何编写代码。

我应该在urls.py 中创建一个路径吗? path('tag/<str:tagslug>', views.tag, name='tag'), 这样我就可以访问views.py中的网址?

如何编写 ORM 以通过 views.py 中的标签过滤文章?

任何帮助将不胜感激:) 谢谢

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 %}

【问题讨论】:

    标签: django django-models django-views django-templates django-orm


    【解决方案1】:

    您可以先进行设置,这样当用户单击标签时,它会通过 POST 请求将标签名称发送到服务器。然后,您可以通过标签名称过滤文章并将新上下文返回到模板。

    这样做的问题是,除非您通过 AJAX 或使用 e.preventdefault(),否则您将刷新页面。

    如果您要在一个需要 HTTP 请求的页面上执行多项操作,我强烈建议您避免页面刷新。

    当用户选择一个标签时,像这样发出一个 Ajax 请求:

    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}
        })
    }
    

    然后使用标签过滤你的数据并通过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)
    
    

    最后,获取响应并将其插入到它所属的 HTML 中。您将从 Javascript 文件中的 AJAX 调用返回中获得响应。

    【讨论】:

    • 非常感谢您!我现在有一个工作的方向。我尝试了您提到的内容,但收到了 POST 403 禁止错误。你能告诉我如何解决这个问题以及如何在 HTML 中呈现数据吗?
    • 当您收到此错误时是否打开了控制台,以便您了解更多上下文?在 Chrome 上,右键单击,检查,单击控制台选项卡并再次运行该操作。它应该让您更清楚地了解引发错误的原因。你在传递一个 CSRF 令牌吗?
    • 控制台上的错误上下文类似于jquery-3.6.0.min.js:formatted:3919 POST http://127.0.0.1:8000/all-articles 403 (Forbidden)。对不起,我是 web 开发的菜鸟,通过传递 CSRF 令牌你的意思是在 all-articles.html 中写 {% csrf_token %}?我已经这样做了,但如果 CSRF 令牌还有更多内容,请告诉我。
    • 可能问题出在 html 文件中?我不太相信这是对的.. &lt;form action="" method="post"&gt; {% csrf_token %} {% for i in all_tags%} &lt;p&gt;{{ i.tag }}&lt;/p&gt; {% endfor %} &lt;/form&gt;
    • 如果你使用的是Ajax,你需要通过AJAX在data参数中传递CSRF token。 Django 模板语言在这里不起作用。有很多资源可以解释如何做到这一点......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-24
    • 2020-10-21
    • 2011-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-01
    相关资源
    最近更新 更多