07 用URL正则实现文章链接跳转

1、概述

本篇主要介绍主要使用Django实现文章列表页向详情页的跳转,在此过程中涵盖了对URL使用正则、让文章评论与文章对应、使用视图分离的处理不同的请求。

2、对URL使用正则,实现文章跳转

1)可以使用类似python中的正则表达式,实现对url的正则,如下:

  • 顾头式结构 r'^detail

说明:符号^为顾头式结构,表示detail首部固定,但detail后可以随意添加,对url访问不受影响。如/detail/abc/efg和/detail12345,这两种与上述代码访问方式没区别。

  • 顾尾式结构 /detail$

说明:符号$为顾尾式结构,表示detail尾部固定,不能再尾部添加东西,否则url不能正确访问。

  • 限定三位数字 /detail/(\d){3}
说明:(\d){3}表示url可以在/detail/后面添加3位数字,3表示数字的个数。
  • 限定多为数字 /detail/(\d+)
说明:(\d+)表示url可以在/detail/后面添加多位数字.

2)实现文章跳转的思路

网页中的每篇文章都有唯一的id号,所以我们可以通过获取该文章的id来唯一检索这篇文章。也就是说,我们可以在原来访问网址后面加上id号来表示访问对应的文章。

因此,在url的访问中,首先要输入对应的访问网址 + id,如下:

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^index', index, name='index'),
    url(r'^detail/(?P<page_num>\d+)$', detail, name='detail'),] #3
说明:#3行的url网址通过url正则格式(?P<page_num>\d+),当向网址多输入id时,id会通过page_num参数传入视图中,相应视图如下:

def detail(request, page_num):
    article = Article.objects.get(id=page_num)
    context['article'] = article
解析:通过get()方法取出对应id的文章,然后在模板层进行渲染,渲染格式如下:

<a href="{% url 'detail' article.id %}">
      <h1 class="ui header">
          {{ article.headline }}
      </h1>
 </a>

解析:模板中的href通过模板标签的方式,其中url ‘detail’代表对应的url是detail,也就是url中的name='detail',然后网址后加article.id,如下图:

说明:其中My father这篇文章就是数据库中第一篇文章,django后台如下:

3、让文章评论与文章对应

1)models.py层

实现这部分的功能,主要是修改数据表结构。文章对于文章评论,是属于一对多的关系,在数据库中我们要在多的一方设置外键,在django中models.py层修改

结构如下:

class Comment(models.Model):
    name = models.CharField(null=True, blank=True, max_length=50)
    comment = models.TextField()
    belong_to = models.ForeignKey(to=Article, related_name="under_comments", null=True,blank=True)
    best_comment = models.BooleanField(default=False)
    def __str__(self):
        return self.name
解析:在Comment数据表中添加belong_to字段,属于Foreignkey的类型,在括号中可以看出是从属于Article,关联名字是under_comments(Article可以通过该关联名字访问评论Comment)。同时设置了一个字段best_comment,属于BooleanField类型,就是可以设置该文章是否是最优评论。
2)通过Article来访问评论方法

def detail(request, page_num, error_form=None):
    context = {}
    form = CommentForm()
    article = Article.objects.get(id=page_num)
    context['article'] = article
    return render(request, 'detail.html', context)
解析:以上是views.py层通过文章的id来得到访问的文章,然后在模板中用article来访问,如下:

{% for comment in article.under_comments.all  %}
  <div class="comment">
      <div class="avatar">
          <img src="http://semantic-ui.com/images/avatar/small/matt.jpg" alt="" />
      </div>
      <div class="content">
          <a href="#" class="author">{{ comment.name }}</a>
          <div class="metadata">
              <div class="date">2 days ago</div>
          </div>
          <p class="text" style="font-family: 'Raleway', sans-serif;">
              {{ comment.comment }}
          </p>
      </div>
  </div>
{% endfor %}
解析:通过模板标签,article.under_comment.all来得到评论列表,其中under_comment就是数据表中对应的关联名。

3)通过Comment来访问评论的方法(这边访问最优评论)

def detail(request, page_num, error_form=None):
    context = {}
    best_comment = Comment.objects.filter(best_comment=True, belong_to=article)
    if best_comment:
        context["best_comment"] = best_comment[0]
解析:通过Comment数据表过滤filter的方法,括号中是相应的条件,如果存在best_comment,则返回的是最优评论的列表,

4)在Models.py层添加最优评论

{% if best_comment %}
    <div class="ui mini red left ribbon label">
        <i class="icon fire"></i>
        Best
    </div>
    <div class="best comment">
        <div class="avatar">
            <img src="http://semantic-ui.com/images/avatar/small/matt.jpg" alt="" />
        </div>
        <div class="content">
            <a href="#" class="author">{{ best_comment.name }}</a>
            <div class="metadata">
                <div class="date">2 days ago</div>
            </div>
            <p class="text" style="font-family: 'Raleway', sans-serif;">
                {{ best_comment.comment }}
            </p>
        </div>
    </div>
{% endif %}
解析:通过判断best_comment是否存在来决定是否添加。如下为Django中设为最优评论的评论:

在网页中的显示为:

4、实现视图分离操作

在视图中即存在GET请求,又存在POST请求时,通常的做法要使用视图分离,将GET和POST进行分离。

1)在view.py层进行分离

def detail(request, page_num, error_form=None):
    context = {}
    form = CommentForm()
    article = Article.objects.get(id=page_num)
    best_comment = Comment.objects.filter(best_comment=True, belong_to=article)
    if best_comment:
        context["best_comment"] = best_comment[0]
    context['article'] = article
    if error_form is not None:
        context['form'] = error_form
    else:
        context['form'] = form
    return render(request, 'detail.html', context)

def detail_comment(request, page_num):
    form = CommentForm(request.POST)
    if form.is_valid():
        name = form.cleaned_data['name']
        comment = form.cleaned_data['comment']
        a = Article.objects.get(id=page_num)
        c = Comment(name=name, comment=comment, belong_to=a)
        c.save()
    else:
        return detail(request, page_num, error_form=form)
    return redirect(to='detail',page_num=page_num)
解析:detail视图为详情页的GET请求,detail_comment为提交评论时的POST请求,其中表单的渲染方式是不同的。

2)在url.py层添加url

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^index', index, name='index'),
    url(r'^detail/(?P<page_num>\d+)$', detail, name='detail'),
    url(r'^detail/(?P<page_num>\d+)/comment$', detail_comment, name='comment'),
]
注意:添加的最后一个url是为了在网页中提交表单时,能访问detail_comment视图,需要在模板层进行修改如下:

<form class="ui error tiny form" action="{% url 'comment' article.id %}" method="post">
  {% if form.errors  %}
    <div class="ui error message">
      {{ form.errors }}
    </div>
     ......
    <button type="submit" class="ui blue button" >Click</button>
</form>
解析:在form标签的action中添加提交评论需要访问的网页,url 'comment'代表url网页,然后加article的id.










  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值