首页 > 解决方案 > django 模板 url 匹配的工作原理

问题描述

我试图弄清楚 django 模板中的 url 匹配是如何工作的。我想要实现的是,当点击一个链接时,它会弹出一个特定的对象。

模型.py

class PostManager(models.Manager):
    def get_queryset(self):
        return super(PostManager,self).get_queryset().filter(status='published')

class Post(models.Model):
    STATUS_CHOICES = (('published','Published'),
                        ('draft','Draft '))
    FIELD_CHOICES = (('1','1 Title and body field'),
                    ('2','2 Title and body fields'),
                    ('3','3 Title and body fields'),
                    ('4', '4 Title and body fields'),
                    ('5', '5 Title and body fields'))

    author = models.ForeignKey(User,
                                on_delete=models.CASCADE,
                                related_name='blog_post')


    title = models.CharField(max_length=100)
    sub_title = models.TextField(max_length=50,default="")

    title_1 = models.CharField(max_length=100,null=True,blank=True)
    title_1_body = models.TextField(null=True,blank=True)


    title_2 = models.CharField(max_length=100,null=True,blank=True)
    title_2_body = models.TextField(null=True,blank=True)


    title_3 = models.CharField(max_length=100,null=True,blank=True)
    title_3_body = models.TextField(null=True,blank=True)



    title_4 = models.CharField(max_length=100,null=True,blank=True)
    title_4_body = models.TextField(null=True,blank=True)


    title_5 = models.CharField(max_length=100,null=True,blank=True)
    title_5_body = models.TextField(null=True,blank=True)

    created = models.DateField()
    publish = models.DateTimeField(default=timezone.now)
    slug = models.SlugField(max_length=250,
                            unique_for_date='created')

    status = models.CharField(max_length=250,
                    choices=STATUS_CHOICES,
                    default='draft')


    object = models.Manager()
    postManager = PostManager()


    class Meta():
        ordering = ('publish',)

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('post_detail',
                        args=[self.slug])

def get_image_filename(instance, filename):
    title = Post.title
    slug = slugify(title)
    return "media/%s-%s" % (slug, filename)


class Image(models.Model):
    post = models.ForeignKey(Post,
                            on_delete=models.CASCADE,
                            related_name='images')

    image_1 = models.ImageField(upload_to=get_image_filename,default='123.jpg',verbose_name="Image",null=True)
    image_2 = models.ImageField(upload_to=get_image_filename,default='123.jpg',verbose_name="Image",null=True)
    image_3 = models.ImageField(upload_to=get_image_filename,default='123.jpg',verbose_name="Image",null=True)
    image_4 = models.ImageField(upload_to=get_image_filename,default='123.jpg',verbose_name="Image",null=True)
    image_5 = models.ImageField(upload_to=get_image_filename,default='123.jpg',verbose_name="Image",null=True)

视图.py

def post_detail(request):
    post = get_object_or_404(Post)
    return render(request, 'blog_application/templates/single.html',
                            {'post':post})

索引.html

{% for elem in posts %}

                <p class="mb-md-5">A small river named Duden flows by their place and supplies it with the necessary regelialia</p>
                    <p><a href="{ url elem.get_absolute_url }" class="btn btn-black px-3 px-md-4 py-3">Read More <span class="icon-arrow_forward ml-lg-4"></span></a></p>

            {% endfor %}

网址.py

path('post_detail/<slug:slug>',views.post_detail,name='single'),
path('', views.show_index, name='index'),

我不太明白 url 匹配和链接如何适用于模板。有人可以根据我的例子来解释一下吗?

标签: djangodjango-urls

解决方案


在我潜水之前,让我们同意 slug 只是一个花哨的名字,它只是一个字符串而已。

好的,所以你想了解 django urls 是如何工作的。 请退后

  • 让我们首先了解 URL 的工作原理,假设我将打开这个网站 www.example.com 并按原样打开它,该网站只是打开对吗?您希望主页在那里

  • 现在,让我们将其打开为 www.example.com?text=welcome

在 chrome 中按 F12 并切换到网络选项卡,基本上发生的事情是您在网络选项卡的最底部添加了一个在 chrome 中显示为“查询字符串参数”的参数,这表示您想使用名为的参数访问此网站包含字符串 hello 的文本

好的,现在这个和问题之间有什么关系?请忍受我

想象一下,我有一个带有帖子的社交网站,并且我想为每个帖子创建一个代码“slug”,以便当它作为 URL 中的参数输入时,它会获取该特定帖子

现在,这是你的 urlpatterns.py

path('post_detail/<slug:slug>', views.post_detail, name='single'),
path('', views.show_index, name='index'),

为简单起见,我假设这是项目级别的 urls.py。

用户在没有任何 url 参数或子页面的情况下访问该网站,它只是调用您的views.show_index

现在用户访问你的website/post_detail/,发生的事情是查看 urlpatterns 中是否有任何与此匹配的 urlpattern,但它没有,所以它只是一个 404

现在用户访问您的website/post_detail/ANY_RANDOM_TEXT

发生的事情是实际上有一个 urlpatternwebsite/post_detail/ANY_RANDOM_TEXT 匹配path('post_detail/<slug:slug>', views.post_detail, name='single')

因此,“ANY_RANDOM_TEXT”肯定是 slug,那我们就当成 slug 吧!

现在我们有了 slug,urlpattern 将调用 views.post_detail(函数或视图)并将 slug 传递给它,所以我们必须接受它对吗?

def post_detail(request, slug):
    post = get_object_or_404(Post, slug=slug)
    return render(request, 'blog_application/templates/single.html',
                            {'post':post})

现在您可以访问“slug”,它只是“ANY_RANDOM_TEXT”,因为我们匹配了它,现在获取与 url 中的 slug 相同的帖子并渲染它!

顺便说一句,不要忘记任何 urlpattern 末尾的斜线,否则世界会爆炸


推荐阅读