1、cookie和session
  cookie可以单独工作
  cookie也可以和session配合来用
  每一个浏览器都会有一个cookie:{}
  浏览器第一次访问服务器的时候cookie是空的
  服务器需要让客户端保存一些数据cookie {"sessionID":"随机字符串"},当下次请求的时候就会带着一些你保存的数据
  django_session表里的每一条记录就是一个个用户,类似一个大的字典
  session_key:存的是sessionID对应的值
  session_data:{"":"","":"",...}存的是一组组键值对
  等再次访问的时候就会带着sessionID


2、登录和注册
  - 登录(ajax)
    - 涉及验证码的实现(可以吧获取的验证码存放在session中,以方便验证的时候判断。每次访问的时候浏览器都会带着你存放在里面的值,用的时候取它就行了)
    - 登录成功之后设置session,以后每次请求进来的时候浏览器都会带着cookie,就知道是谁进来了。保存了状态。(用auth模块)

user=auth.authenticate(username=username,password=password)#验证用户名和密码
if user:
ret["flag"] = True
auth.login(request,user) #session request.session["flag"]=True    #如果认证成功,就让登录,这个login里面包括了session操作和cookie
...

    如果是当前的用户就做什么操作,如果不是当前的用户就不让他进
  - 注册(ajax+Form)
    - 涉及头像的实现
    具体见上篇博客
3、系统主页
1、设计系统主页(系统主页是用户不管登录不登录都是可以看到的,所以没必要进行验证)
  - 导航条:
    - 需要注意的是:
    - 如果用户是登录进来的,就让显示登录状态;如果用户还没有登录,就在导航条上显示登录,注册(如图)

登录状态

没有登录状态

   所以具体我们还得判断一下

 {% if request.user.is_authenticated %}
         <li class="active"><a href="#"><span
               class="glyphicon glyphicon-user"></span>{{ request.user.username }}</a></li>
         <li class="active"><a href="/log_out/">注销</a></li>
  {% else %}
         <li class="active"><a href="/login/">登录</a></li>
         <li class="active"><a href="/register/">注册</a></li>
  {% endif %}

  - 注销
  - 修改密码
  像是注销,登录,修改密码我们都可以借助auth模块来实现

  - 具体显示内容可以分三大块
    - 左侧菜单系列
    - 显示文章系列
      - 文章标题:
      - 作者头像:
      - 是谁发布的,发布时间,等...
      - 文章不可能只有一篇,会有好多篇文章,这是还得加上分页
    - 右侧可以放一写其他信息

2、下面是具体流程,需要注意的知识点
    ====================================
    当做左侧的时候需要多加两张表
      - 多加了一个网站分类表和网站文章分类表(可参考博客园cnblogs.com的系统主页)
      - 一个网站分类里面又可以对文章分好多类 (建立了一对多的关系)
      - 文章分类里面又有好多相关的具体文章(建立了一对多的关系) 注意关联字段要写在多的一方

class SiteCategory(models.Model):
    '''网站分类表'''
    name = models.CharField(max_length=32,verbose_name="分类名")
    class Meta:
        verbose_name_plural="网站分类表"
    def __str__(self):
        return self.name

class SiteArticleCategory(models.Model):
    '''网站文章分类表'''
    name = models.CharField(max_length=32,verbose_name="分类名")
    sitecategory = models.ForeignKey(to="SiteCategory",verbose_name="所属网站")

    class Meta:
        verbose_name_plural = "网站文章分类表"
    def __str__(self):
        return self.name

 

    ====================================
    - 建立好关系之后就可以实现左侧菜单了
      - 左侧菜单需要注意的是你点击菜单的时候的跳转路径,当然有人会想到用模板继承的方式,这种方式是能实现,但是还有一种更机智的办法。我们可以参考博客园的跳转路径,还是继续走index视图,
      但是我们得把路径匹配一下,如图

url(r'^index/', views.index),
url(r'^$', views.index), #根目录下也让走index
url(r'^cate/(?P<site_article_category>.*)/', views.index) #有名分组

 


注意:
  【1】
    这时得注意,你的index现在有两个路径了,所以我们不能直接把site_article_category传进去, 我们得用一个**kwargs来接受(因为你的url(r'^login/$', views.login)这个路径是没有参数的,
    如果你直接吧site_article_category这样传进去,就会报错了,区分不了要走有路径的还是要走没有路径的,所以我们用**kwargs),当有参数的时候,有名分组是按照关键字传参数的,所以会把传进来的值                 以字典的形式让kwargs接收;当没有参数的时候。就走index/路径,直接显示index首页就行了
  【2】
    当两个路径有冲突的时候,一定要把规则少的放在匹配多的上面,不然就会给覆盖了
  【3】
    在模板中渲染的时候,需要在后端先把数据查出来,然后在前端渲染
    ====================================
    - 显示文章系列
    - 查出所有的文章,渲染在页面(以及标题啊什么的,只要有article对象了,渲染的时候在页面中用.的方式,就可以查到信息了)
    需要注意的是:这里需要判断一下。具体如下

print("-----------",kwargs) #接收到的是一个字典
kwargs = kwargs.get("site_article_category")
print("=======",kwargs) #得到的是site_article_category对应的值
if kwargs:
  print("xxxxxxxxxxxxxx")
  article_obj = models.Article.objects.filter(site_article_category__name=kwargs) # article_obj打印的是一个对象 ,如果点击的是左侧的,就让现实左侧的相关文章
else:
  article_obj = models.Article.objects.all()#如果没有点击左侧就查询所有的文章

  - 点击头像跳转

<div class="avatar col-md-2">
<a href="{% url 'aaa' article.user.username %}"> <!-- 跳转路径--> 这里是用到了
<img src="{{ article.user.avatar.url }}" alt="" width="60" height="60"></a><!-- 图片路径-->
</div>

注意:
  【1】:跳转路径

<a href="{% url 'aaa' article.user.username %}"> <!-- 跳转路径--> 这里是用到了反向解析(按照别名去匹配路径),因为url现在是有参数的,所以后面还得加上参数 
url(r'^(?P<username>.*)/$', views.homesite, name='aaa'), 

  【2】:图片路径有两种方式:

1、我们也可以指定/media/{{article.user.avatar}}
2、直接{{article.user.avatar.url}} django会自动找到图片对应的位置

  - 分页

{% if article_obj.has_previous %}
<li class="previous"><a href="{{ request.path_info }}?page={{ article_obj.previous_page_number }}">上一页</a></li>
{% else %}
<li class="previous disabled"><a href="#">上一页</a></li>
{% endif %}

注意:
  【1】:一定要把跳转路径对应好了,不然就混乱了。

4、个人主页
设计个人主页的时候,可以仿照博客园的页面设计,当然每个人的个人主页都是不一样的,不过这个也挺简单的,下面会说到
我设计的个人主页:还是分了三大块
  - 导航条:
  - 左侧:
    - 个人信息
    - 我的标签
    - 随笔分类
    - 日期归档
  - 右侧:显示文章
  - 涉及到的知识点
  1、模板继承
    当点击文章标题的时候用到,因为当点击文章标题的时候,就要显示具体的文章内容
    这时候需要再走一个路由,专门处理具体的文章内容的操作

 标题#}
<div class="title">
  <h4><a href="/blog/{{ current_user.username }}/articles/{{ article.id }}">{{ article.title }}</a></h4>
</div>

  url:这里用到的是路由分发。。。

 url(r'^(?P<username>.*)/articles/(?P<article_id>\d+)/$', views.article_detail),

  注意:在admin录入文章内容数据的时候,如果你直接吧随便找的文章粘贴过来,这样粘贴过来的是没有样式的,我们要把html源码粘贴进去
       当吧源码粘贴进去的时候会全部都是标签,而不是文章内容,这是由于做了安全机制了,吧标签当成是字符串了,我们得告诉浏览器。
     我的代码是安全的,这样才会显示中文。
  解决办法:safe <p>{{ article_obj.article_detail.content|safe }}</p>
  2、ORM查询
    1、查询操作

# 查询当前用户下的所有文章
current_user = models.UserInfo.objects.filter(username=username).first()
models.Article.objects.filter(user=current_user)
#查看当前用户的个人博客,(个人博客和用户是一对一的关系,一个用户有一个个人博客)
current_user.blog
#查询当前用户下的而所有的分类以及文章数
models.Classfication.objects.filter(blog=current_blog).annotate(count=Count("article__title")).values_list("title","count")
#查询当前用户下的而所有的标签以及文章数
models.Tag.objects.all().filter(blog=current_blog).annotate(count=Count("article__id")).values_list("name","count")
#查询当前用户下的而所有的年月日期以及文章数
models.Article.objects.all().filter(user=current_user).extra(select={"filter_create_date":"strftime('%%Y/%%m',create_time)"}).values_list("filter_create_date").annotate(Count("title"))

涉及:
  基于对象查询

  基于双下划线,分组函数 annotate

理解分组:

  查日期的时候:extra过滤

  3、左侧的标签分类和随笔分类,日期归档,当点击的时候跳转,参照博客园的跳转路径,具体操作和系统主页的类似,不需要模板继承,也不需要跳转到其他的地方,让还在当前页面上跳转
  我们可以吧跳转路径匹配一下
  url(r'^(?P<username>.*)/(?P<condition>category|tag|data)/(?P<para>.*)/$', views.homesite),

  在HTML中:

日期归档,
<p><a href="/blog/{{ current_user.username }}/data/{{ data.0 }}/">{{ data.0 }}({{ data.1 }})</a></p>
随笔分类
<p><a href="/blog/{{ current_user.username }}/category/{{ category.0 }}/">{{ category.0 }}({{ category.1 }})</a></p>
标签分类
<p><a href="/blog/{{ current_user.username }}/tag/{{ tag.0 }}/">{{ tag.0 }}({{ tag.1 }})</a></p>

  4、每个人都有一套默认的皮肤
    1、在static下创建一个存皮肤的文件夹user_home_style
      a.css 设置a样式
      b.css 设置b样式
      ....
    2、吧homesite里面的你不想用的样式删除了
    3、在数据库里吧theme主题修改一下,存成  a.css
                        b.css
                        ....
    4、导入:在link的时候{{current_user.blog.theme}}

<link rel="stylesheet" href="/static/user_home_style/{{ current_user.blog.theme }}"> #这样就每个用户对应的样式就找到了

5、个人主页的文章详细以及点赞和评论

  涉及到的知识点:
    - ajax
    - F查询

  点赞思路:用ajax实现:
    发送数据,要对那篇文章点赞,需要发一个article_id
    还需要知道当前用户的id,这个我们可以不用ajax发了,直接在后端查出来,用request.user.nid
    在后端接收数据
      先创建赞示例
      models.Article_poll.objects.create(user_id=user_id,article_id=article_id)
      然后点赞数+1
      models.Article.objects.filter(id=article_id).update(poll_count=F("poll_count")+1)
    然后返回给前端,在前端渲染
    渲染的时候
      1、吧页面上的数字加1,并且显示点赞成功
      2、如果已经点过赞了,提示不能重复点赞,
      3、如果是用户登录了可以点赞,没有登录提示请先登录,登录做个超链接,链接到login页面
6、url:路径斜杠问题
  当加/的时候,是从根目录拼接
  当没有加/的时候,是从当前路径拼接
7、 查看当前用户

current_user = models.UserInfo.objects.filter(username=username).first()
print("current_user==========",current_user,type(current_user)) 
print("request.user.username======",request.user.username,type(request.user.username))
打印结果 
current_user========== haiyan <class 'app01.models.UserInfo'> #对象
request.user.username====== haiyan <class 'str'> #字符串,,可以在页面中渲染

 


 

posted on 2017-11-25 17:31  海燕。  阅读(1545)  评论(0编辑  收藏  举报