这篇应该是2017年的最后一篇博客了,在这里首先祝大家元旦快乐!

从这篇博客开始,将会介绍Blogs App的功能实现,包括数据模型的建立、相关功能的视图函数的实现、前端页面的设计等,这意味着我们即将可以书写真正的博客了。

首先来建立我们的Blogs App,方法同建立Users App,即在manage.py目录下输入以下命令:

  1. python3 manage.py startapp blogs
python3 manage.py startapp blogs

在建立了Blogs App后,我们首先要建立它的数据模型。Blogs App包括三张表:Blog、Comment和Category。Blog表包括博客的标题、作者等主要信息;Comment存储博客的评论内容,而Category是博客的分类。Blog表的model如下:

  1. # blogs/models.py
  2. # -*- coding=utf-8 -*-
  3. from django.db import models
  4. from users.models import Users
  5. from ckeditor_uploader.fields import RichTextUploadingField
  6. from django.utils import timezone
  7. class Blog(models.Model):
  8. title = models.CharField(max_length=32,verbose_name=u'标题')
  9. auther = models.ForeignKey(Users,default='')
  10. category = models.ForeignKey(Category,null=True)
  11. content = RichTextUploadingField(verbose_name=u'内容')
  12. createdate = models.DateTimeField('Create time',default=timezone.now())
  13. modifydate = models.DateTimeField('Modify time',default=timezone.now())
  14. readcount = models.IntegerField(default=0)
  15. # Add comment count
  16. commentcount = models.IntegerField(default=0,null=True,blank=True)
  17. draft = models.BooleanField(default=True)
  18. @classmethod
  19. def create(cls,title,authername,category,content,createdate,modifydate):
  20. blog = cls(title=title,auther=authername,category=category,content=content,createdate=createdate,modifydate=modifydate)
  21. return blog
  22. def __unicode__(self):
  23. return self.title
# blogs/models.py
# -*- coding=utf-8 -*-
from django.db import models
from users.models import Users
from ckeditor_uploader.fields import RichTextUploadingField
from django.utils import timezone class Blog(models.Model):
title = models.CharField(max_length=32,verbose_name=u'标题')
auther = models.ForeignKey(Users,default='')
category = models.ForeignKey(Category,null=True)
content = RichTextUploadingField(verbose_name=u'内容')
createdate = models.DateTimeField('Create time',default=timezone.now())
modifydate = models.DateTimeField('Modify time',default=timezone.now())
readcount = models.IntegerField(default=0)
# Add comment count
commentcount = models.IntegerField(default=0,null=True,blank=True)
draft = models.BooleanField(default=True) @classmethod
def create(cls,title,authername,category,content,createdate,modifydate):
blog = cls(title=title,auther=authername,category=category,content=content,createdate=createdate,modifydate=modifydate)
return blog def __unicode__(self):
return self.title

Blog model的字段如下:

title: 博客标题,最长32

auther: 作者,是Users的外键

category: 类别,是Category的外键

content: 博客的正文。这里使用了CKeditor编辑器提供的富文本域来存储博客的正文,以便之后的图文混排操作。CKeditor的部分将在后面介绍。

createdate: 博客的发表时间,这里的时间用的是timezone.now(),即使用settings.py中定义的时区来决定当前的时间。

modifydate: 博客的修改时间

readcount: 博客的阅读数

commentcount: 博客拥有的评论数

draft: 草稿标记,当为True时表示博客为草稿状态,将不会在主页出现;当为False时博客为正文状态,将在正文出现。

下面是Category model和Comment model:

  1. # blogs/models.py
  2. # ...
  3. class Category(models.Model):
  4. categoryname = models.CharField(max_length=8,unique=True)
  5. blogcount = models.IntegerField()
  6. def __unicode__(self):
  7. return self.categoryname
  8. class Comment(models.Model):
  9. attachedblog = models.ForeignKey(Blog)
  10. content = models.TextField()
  11. auther = models.ForeignKey(Users,default='')
  12. createtime = models.DateTimeField('Comment Create time')
  13. @classmethod
  14. def create(cls,attachedblog,content,authername,createtime):
  15. comment = cls(attachedblog=attachedblog,auther=authername,content=content,createtime=createtime)
  16. return comment
  17. def __unicode__(self):
  18. return self.content
# blogs/models.py
# ...
class Category(models.Model):
categoryname = models.CharField(max_length=8,unique=True)
blogcount = models.IntegerField() def __unicode__(self):
return self.categoryname class Comment(models.Model):
attachedblog = models.ForeignKey(Blog)
content = models.TextField()
auther = models.ForeignKey(Users,default='')
createtime = models.DateTimeField('Comment Create time') @classmethod
def create(cls,attachedblog,content,authername,createtime):
comment = cls(attachedblog=attachedblog,auther=authername,content=content,createtime=createtime)
return comment def __unicode__(self):
return self.content

Category model比较简单,只有两个字段:categoryname类别名和blogcount博客数量。

Comment model相对复杂一些:

attachedblog:每篇评论都要属于一篇博客,该字段表明评论属于哪篇博客

content:评论内容

auther:评论的作者

createtime:评论的发表时间

在建立好这些model后,和Users App一样,我们来做一些基本的配置工作:在blogs/apps.py和blogs/admin.py中注册这些model和App,并将Blogs App加入到myblog/settings.py中。

  1. # blogs/apps.py
  2. from django.apps import AppConfig
  3. class BlogsConfig(AppConfig):
  4. name = 'blogs'
# blogs/apps.py
from django.apps import AppConfig
class BlogsConfig(AppConfig):
name = 'blogs'
  1. # blogs/admin.py
  2. from django.contrib import admin
  3. from .models import Blog,Category
  4. # Register your models here.
  5. admin.site.register(Blog)
  6. admin.site.register(Category)
# blogs/admin.py
from django.contrib import admin
from .models import Blog,Category
# Register your models here.
admin.site.register(Blog)
admin.site.register(Category)
  1. # myblog/settings.py
  2. # ...
  3. INSTALLED_APPS = [
  4. 'blogs.apps.BlogsConfig',
  5. 'users.apps.UsersConfig',
  6. # ...
  7. ]
  8. # ...
# myblog/settings.py

# ...
INSTALLED_APPS = [
'blogs.apps.BlogsConfig',
'users.apps.UsersConfig',
# ...
]
# ...

在完成了这些琐碎的小配置后,我们就可以开始编写我们的视图函数了。Blogs App涉及到的视图函数相对比较复杂,因此在这篇博客中先介绍三个核心功能的后端实现:浏览、发布博客以及保存草稿。

首先来看浏览功能的实现。浏览功能,即根据Blog的id得到其相关内容并显示在页面上,相对比较简单,代码如下:

  1. # blogs/views.py
  2. def content(request,blogId):
  3. blog = Blog.objects.get(id=blogId)
  4. comment = Comment.objects.filter(attachedblog=blog)
  5. request.session['currblogId'] = blogId
  6. blog_title = blog.title
  7. blog_content = blog.content
  8. blogContent = {
  9. 'blog_title':blog_title,
  10. 'content':blog_content,
  11. 'comment_list':comment
  12. }
  13. blog.readcount+=1
  14. blog.save()
  15. return render(request,'blogs/content.html',blogContent)
# blogs/views.py
def content(request,blogId):
blog = Blog.objects.get(id=blogId)
comment = Comment.objects.filter(attachedblog=blog)
request.session['currblogId'] = blogId
blog_title = blog.title
blog_content = blog.content
blogContent = {
'blog_title':blog_title,
'content':blog_content,
'comment_list':comment
}
blog.readcount+=1
blog.save()
return render(request,'blogs/content.html',blogContent)
  1. # blogs/urls.py
  2. from django.conf.urls import url
  3. from . import views
  4. from django.conf.urls import include
  5. from users import urls as userurls
  6. app_name='blogs'
  7. urlpatterns = [
  8. url(r'^(?P<blogId>[0-9]*)$', views.content, name='content'),
  9. # ...
  10. ]
# blogs/urls.py
from django.conf.urls import url
from . import views
from django.conf.urls import include
from users import urls as userurls
app_name='blogs'
urlpatterns = [
url(r'^(?P<blogId>[0-9]*)$', views.content, name='content'),
# ...
]

在content函数中,通过blogId可以获得到唯一的Blog对象,进而拿到博客的标题、正文和从属于该博客的所有评论。随后,使用session记录下正在访问的博客的id,以便后面发布评论使用。在获得了博客的相关信息后,便可以将其放在一个字典里传给前端以供显示;然后,我们要使该博客的访问量+1,并更新在数据库中。
在前端部分,同Users App一样,我们需要在blogs/templates中建立模板,并在其中建立blogs目录存放我们的页面。由于和Users App模板大同小异,因此这里不再放模板的代码;content页面代码如下:

  1. <!-- blogs/templates/blogs/content.html -->
  2. {% extends "blogTemplate.html" %}
  3. {% block content %}
  4. <div class="content">
  5. <h2>{{ blog_title }}</h2>
  6. {{ content|safe }}
  7. </div>
  8. <p><a href="{% url 'index' %}">返回首页</a></p>
  9. {% endblock %}
  10. {% block comment %}
  11. {% if comment_list %}
  12. {% for comment in comment_list %}
  13. <ul class="comment">
  14. <li>
  15. {% if comment.auther.username == "anony" %}
  16. <h4>匿名用户    {{ comment.createtime|date:"Y-m-d H:i:s" }}</h4>
  17. {% else %}
  18. <img src="{{ comment.auther.logoimage.url }}" width="64" height="64" />
  19. <h4>{{ comment.auther }}    {{ comment.createtime|date:"Y-m-d H:i:s" }}</h4>
  20. {% endif %}
  21. </li>
  22. <li>{{ comment.content|safe }}</li>
  23. </ul>
  24. <hr/>
  25. {% endfor %}
  26. {% else %}
  27. <ul class="comment">
  28. <p>还没有人发表评论</p>
  29. </ul>
  30. {% endif %}
  31. <span>评论 </span>
  32. <form action="{% url 'blogs:saveComment' %}" method="post" onsubmit="return toVaild()">
  33. {% csrf_token %}
  34. <ul class="comment">
  35. <li><textarea name="blogcomment"></textarea></li>
  36. <li><input type="submit" value="提交"></li>
  37. </ul>
  38. </form>
  39. {% endblock %}
<!-- blogs/templates/blogs/content.html -->
{% extends "blogTemplate.html" %}
{% block content %}
<div class="content">
<h2>{{ blog_title }}</h2>
{{ content|safe }}
</div>
<p><a href="{% url 'index' %}">返回首页</a></p>
{% endblock %}
{% block comment %}
{% if comment_list %} {% for comment in comment_list %}
<ul class="comment">
<li>
{% if comment.auther.username == "anony" %}
<h4>匿名用户 {{ comment.createtime|date:"Y-m-d H:i:s" }}</h4>
{% else %}
<img src="{{ comment.auther.logoimage.url }}" width="64" height="64" />
<h4>{{ comment.auther }} {{ comment.createtime|date:"Y-m-d H:i:s" }}</h4>
{% endif %}
</li>
<li>{{ comment.content|safe }}</li>
</ul>
<hr/>
{% endfor %}
{% else %}
<ul class="comment">
<p>还没有人发表评论</p>
</ul>
{% endif %}
<span>评论 </span>
<form action="{% url 'blogs:saveComment' %}" method="post" onsubmit="return toVaild()">
{% csrf_token %}
<ul class="comment">
<li><textarea name="blogcomment"></textarea></li>
<li><input type="submit" value="提交"></li>
</ul>
</form>
{% endblock %}

content页面要显示两部分内容,其一是博客主体内容,包括博客的标题和正文,其二是博客的相关评论,以及发布评论的表单。在博客的正文部分有一个地方需要注意,就是我们的博客是以富文本形式存储在数据库中的,因此博客正文包含很多html标记。在显示的时候我们需要用|safe标记来表明这个内容是安全的,可以将内容转义以得到正确的格式。如果没有加上|safe,我们看到的就是带有html标记的原始数据。
在显示评论的部分,我们会逐条显示评论的内容以及发布时间,并且如果是非匿名评论,我们会显示评论者的用户名和头像,如下所示:

下面来让我们看一下如何发布博客。为了实现博客的图文混排,我们选用CKeditor这一款编辑器作为博客的编辑器。这款编辑器是一种免费的富文本编辑器,体积小巧,并且配置方便,支持可见即所得的图文混排,如图所示:

此外,CKeditor还支持多种配置,以实现更强大的功能。在这里我选用了默认的配置。

为了使用CKeditor,我们需要到官网上下载CKeditor,然后把解压后得到的ckeditor目录拷贝到我们在myblog目录下建立的static目录下。此外,我们还要安装Django的ckeditor库django-ckeditor,这样我们就可以在工程中使用ckeditor了(static的部分见本系列第三篇)。需要注意的是,ckeditor需要python的pillow库作为处理图像的后端,因此我们还需要安装pillow。

为了使用ckeditor,我们需要在myblog/settings.py中添加一些配置,如下所示:

  1. # myblog/settings.py
  2. # ...
  3. INSTALLED_APPS = [
  4. 'ckeditor',
  5. 'ckeditor_uploader',
  6. # ...
  7. ]
  8. # ...
  9. CKEDITOR_JQUERY_URL = '/static/js/jquery-3.2.1.min.js'
  10. CKEDITOR_UPLOAD_PATH = 'blogimage/'
  11. CKEDITOR_IMAGE_BACKEND = 'pillow'
  12. # ...
# myblog/settings.py
# ...
INSTALLED_APPS = [
'ckeditor',
'ckeditor_uploader',
# ...
]
# ...
CKEDITOR_JQUERY_URL = '/static/js/jquery-3.2.1.min.js'
CKEDITOR_UPLOAD_PATH = 'blogimage/'
CKEDITOR_IMAGE_BACKEND = 'pillow'
# ...

我们需要把ckeditor和它的上传器加入到INSTALLED_APPS中,此外我们还要将ckeditor的上传图片路径和依赖的jquery库路径写在settings.py中。

在配置好CKeditor后,我们就可以开始编写发布博客以及存储草稿的view函数了。我们需要一个ModelForm来发布博客,因此我们建立blogForm.py文件,并建好我们的BlogForm表单:

  1. # blogs/blogForm.py
  2. #-*- coding=utf-8 -*-
  3. from django import forms
  4. from django.forms import ModelForm
  5. from .models import Blog
  6. class BlogForm(ModelForm):
  7. class Meta:
  8. model = Blog
  9. fields = ['title','category','content']
# blogs/blogForm.py
#-*- coding=utf-8 -*-
from django import forms
from django.forms import ModelForm
from .models import Blog class BlogForm(ModelForm):
class Meta:
model = Blog
fields = ['title','category','content']

在定义好BlogForm表单后,我们就可以写发布博客的相关函数了:

  1. # blogs/views.py
  2. def addBlog(request):
  3. if request.method == 'POST':
  4. if request.session.has_key('currentblogId'):
  5. tmpBlog = Blog.objects.get(id=request.session['currentblogId'])
  6. if tmpBlog:
  7. form = BlogForm(request.POST,instance=tmpBlog)
  8. tmpBlog = form.save(commit=False)
  9. tmpBlog.draft = False
  10. tmpBlog.save()
  11. result_info = 'Success'
  12. else:
  13. form = BlogForm(request.POST)
  14. if form.is_valid():
  15. newBlog = form.save(commit=False)
  16. newBlog.auther = Users.objects.get(username=request.session['username'])
  17. newBlog.draft = False
  18. category = Category.objects.get(categoryname=newBlog.category)
  19. category.blogcount = category.blogcount+1
  20. category.save()
  21. newBlog.save()
  22. result_info = 'Success'
  23. del request.session['currentblogId']
  24. else:
  25. form = BlogForm(request.POST)
  26. if form.is_valid():
  27. newBlog = form.save(commit=False)
  28. newBlog.auther = Users.objects.get(username=request.session['username'])
  29. newBlog.draft = False
  30. category = Category.objects.get(categoryname=newBlog.category)
  31. category.blogcount = category.blogcount + 1
  32. category.save()
  33. newBlog.save()
  34. result_info = 'Success'
  35. return HttpResponseRedirect(reverse('blogs:addblogResult', kwargs={'info': result_info}))
  36. else:
  37. form = BlogForm()
  38. return render(request, 'blogs/addblog.html', {'form':form})
  39. def addBlogResult(request,info):
  40. tipMessage=''
  41. if info == 'Success':
  42. tipMessage = '博文已成功发表!'
  43. else:
  44. tipMessage = info
  45. parameters = {'info':tipMessage}
  46. return render(request, 'blogs/addblogResult.html', parameters)
  47. def saveDraft(request):
  48. if request.method == 'POST':
  49. blogId = request.session.get('currentblogId','-1')
  50. if blogId!='-1':
  51. try:
  52. tmpBlog = Blog.objects.get(id=blogId)
  53. form = BlogForm(request.POST, instance=tmpBlog)
  54. tmpBlog = form.save(commit=False)
  55. tmpBlog.draft = True
  56. tmpBlog.save()
  57. result_info = u'文章已保存于草稿箱中。'
  58. return HttpResponse(result_info)
  59. except Blog.DoesNotExist:
  60. form = BlogForm(request.POST)
  61. if form.is_valid():
  62. newBlog = form.save(commit=False)
  63. newBlog.auther = Users.objects.get(username=request.session['username'])
  64. category = Category.objects.get(categoryname=newBlog.category)
  65. category.blogcount = category.blogcount+1
  66. category.save()
  67. newBlog.save()
  68. request.session['currentblogId'] = newBlog.id
  69. result_info = u'文章已保存于草稿箱中。'
  70. return HttpResponse(result_info)
  71. return HttpResponse('test')
  72. else:
  73. form = BlogForm(request.POST)
  74. if form.is_valid():
  75. newBlog = form.save(commit=False)
  76. newBlog.auther = Users.objects.get(username=request.session['username'])
  77. category = Category.objects.get(categoryname=newBlog.category)
  78. category.blogcount = category.blogcount + 1
  79. category.save()
  80. newBlog.save()
  81. request.session['currentblogId'] = newBlog.id
  82. result_info = u'文章已保存于草稿箱中。'
  83. return HttpResponse(result_info)
  84. else:
  85. return HttpResponse('test')
  86. else:
  87. return HttpResponse('test')
# blogs/views.py
def addBlog(request):
if request.method == 'POST':
if request.session.has_key('currentblogId'):
tmpBlog = Blog.objects.get(id=request.session['currentblogId'])
if tmpBlog:
form = BlogForm(request.POST,instance=tmpBlog)
tmpBlog = form.save(commit=False)
tmpBlog.draft = False
tmpBlog.save()
result_info = 'Success'
else:
form = BlogForm(request.POST)
if form.is_valid():
newBlog = form.save(commit=False)
newBlog.auther = Users.objects.get(username=request.session['username'])
newBlog.draft = False
category = Category.objects.get(categoryname=newBlog.category)
category.blogcount = category.blogcount+1
category.save()
newBlog.save()
result_info = 'Success'
del request.session['currentblogId']
else:
form = BlogForm(request.POST)
if form.is_valid():
newBlog = form.save(commit=False)
newBlog.auther = Users.objects.get(username=request.session['username'])
newBlog.draft = False
category = Category.objects.get(categoryname=newBlog.category)
category.blogcount = category.blogcount + 1
category.save()
newBlog.save()
result_info = 'Success'
return HttpResponseRedirect(reverse('blogs:addblogResult', kwargs={'info': result_info}))
else:
form = BlogForm()
return render(request, 'blogs/addblog.html', {'form':form}) def addBlogResult(request,info):
tipMessage=''
if info == 'Success':
tipMessage = '博文已成功发表!'
else:
tipMessage = info
parameters = {'info':tipMessage}
return render(request, 'blogs/addblogResult.html', parameters) def saveDraft(request):
if request.method == 'POST':
blogId = request.session.get('currentblogId','-1')
if blogId!='-1':
try:
tmpBlog = Blog.objects.get(id=blogId)
form = BlogForm(request.POST, instance=tmpBlog)
tmpBlog = form.save(commit=False)
tmpBlog.draft = True
tmpBlog.save()
result_info = u'文章已保存于草稿箱中。'
return HttpResponse(result_info)
except Blog.DoesNotExist:
form = BlogForm(request.POST)
if form.is_valid():
newBlog = form.save(commit=False)
newBlog.auther = Users.objects.get(username=request.session['username'])
category = Category.objects.get(categoryname=newBlog.category)
category.blogcount = category.blogcount+1
category.save()
newBlog.save()
request.session['currentblogId'] = newBlog.id
result_info = u'文章已保存于草稿箱中。'
return HttpResponse(result_info)
return HttpResponse('test')
else:
form = BlogForm(request.POST)
if form.is_valid():
newBlog = form.save(commit=False)
newBlog.auther = Users.objects.get(username=request.session['username'])
category = Category.objects.get(categoryname=newBlog.category)
category.blogcount = category.blogcount + 1
category.save()
newBlog.save()
request.session['currentblogId'] = newBlog.id
result_info = u'文章已保存于草稿箱中。'
return HttpResponse(result_info)
else:
return HttpResponse('test')
else:
return HttpResponse('test')

发布博客的函数分为三部分:addBlog用于发布博客,addBlogResult是在发布博客成功后要跳转的页面,而saveDraft是将博客存储为草稿的函数。

首先来看saveDraft函数的实现。该函数要考虑到两种情况:1、博客的第一次保存;2、博客已存为草稿下的再次保存。对于博客的第一次保存,我们可以直接调用BlogForm的方法进行保存,并且在保存之后将该篇博客的id存储在session['currentblogId']中,以便情况2的使用;对于已经存储为草稿的博客,我们只需根据session['currentblogId']的值得到当前博客,并再次调用save方法保存即可。在这个函数中,我们使用了一种新的方法来初始化BlogForm:form = BlogForm(request.POST,instance=tmpBlog),这是因为我们可以用一个已存在的对象来初始化一个ModelForm。另外,由于我们稍后在前端会以Ajax的方式来调用这个函数,因此我们没有使用render函数来渲染某个页面,而只是简单地返回了一个HttpResponse对象。

再来看addBlog函数的实现。该函数也要考虑两种情况:1、博客已存为草稿后发布;2、博客没有存储为草稿直接发布。对于第一种情况,我们可以直接从session['currentblogId']中得到当前博客的id值,再将其draft的值改为False后调用save方法保存。注意这里的第一次save函数的调用,我们传入了commit=False的选项,这表示此次save并不会真正加载到数据库中,在之后我们还可以对对象的字段值进行修改后再真正commit到数据库中。另外一个需要注意的地方是,我们不仅要在Blog表里插入数据,也要更新category model的blogcount值,使之+1。

addBlogResult函数没什么可说的,就是根据addBlog的结果进行的跳转页面。

以上三个函数的url配置如下:

  1. # blog/urls.py
  2. urlpatterns = [
  3. # ...
  4. url(r'^addblog/$', views.addBlog, name='addblog'),
  5. url(r'^addblogResult/(?P<info>.*)$', views.addBlogResult, name='addblogResult'),
  6. url(r'^saveDraft/$',views.saveDraft,name='saveDraft'),
  7. # ...
  8. ]
# blog/urls.py
urlpatterns = [
# ...
url(r'^addblog/$', views.addBlog, name='addblog'),
url(r'^addblogResult/(?P<info>.*)$', views.addBlogResult, name='addblogResult'),
url(r'^saveDraft/$',views.saveDraft,name='saveDraft'),
# ...
]

这样,我们的发布博客、存储草稿和正文的后端部分就完成了。在下篇博客中,将继续介绍这三个功能的前端页面实现~

Django+Nginx+uwsgi搭建自己的博客(六)的更多相关文章

  1. Django+Nginx+uwsgi搭建自己的博客(五)

    在上一篇博文中,向大家介绍了Users App和Index的前端部分的实现,以及前端与Django的通信部分.至此,我们的博客已经具备一个简单的雏形,可以将其部署在本地的服务器上了.目前较为流行的we ...

  2. Django+Nginx+uwsgi搭建自己的博客(四)

    由于在上篇博文中仍然介绍了相当多的后端部分,导致原定于上篇介绍的前端部分“跳票”到了这篇.在此篇博文中,我将会介绍Users App和主页的前端部分,从而形成我们博客的一个雏形. 在前端部分,我们主要 ...

  3. Django+Nginx+uwsgi搭建自己的博客(一)

    最近对写爬虫有些厌倦了,于是将方向转移到了Web开发上.其实在之前自己也看过一部分Flask的资料,但总觉得Flask的资料有些零散,而且需要的各种扩展也非常多.因此,我将研究方向转移到了另一个主流的 ...

  4. Django+Nginx+uwsgi搭建自己的博客(八)

    在这篇博客中,我们开始为我们的博客开发Blogs App和Users App相关的管理功能,以便每个用户都能管理自己的博客以及评论.目前,Users App的管理功能相对简单,主要功能为查看用户资料以 ...

  5. Django+Nginx+uwsgi搭建自己的博客(七)

    上一篇博客中介绍了Blogs App的部分后端功能的实现,在这篇博客中,将继续为大家介绍Blogs App中前端功能的实现. 首先来看发布博客功能的前端页面.在blogs/templates/blog ...

  6. Django+Nginx+uwsgi搭建自己的博客(二)

    在上一篇博客中,为大家介绍了Django的一些基本概念以及建立了第一个App——Users,并且在数据库中建立了对应的表. 在这篇博客中,将为大家继续介绍数据库模型的定义和相关操作,以及Users A ...

  7. Django+Nginx+uwsgi搭建自己的博客(三)

    (本来打算在这篇博文中介绍Users App的前端部分的,但写着写着就发现还需要铺垫很多东西才能把整个项目串的比较流畅些,因此这篇就继续介绍了后端的一些东西,前端的部分只好跳票到下一篇了-) 在上一篇 ...

  8. python3.x +django + nginx + uwsgi 搭建web服务

    最近一直在用django开发自己的网站.在开发和线上环境的对接过程中遇到了许多的坑.所以想以一个老鸟的经历来写一下怎么 搭建web服务 一.python3.x .django .nginx .uwsg ...

  9. Linux - 搭建Web项目(Django + nginx + uwsgi)

    工作中碰到需要使用Django + nginx + uwsgi 搭建项目环境 1. 搭建基本环境 需要有python环境,不多做说明 需要安装nginx,不多做说明 需要安装uwsgi: yum in ...

随机推荐

  1. 关闭eclipse自动弹出console功能

    使用eclipse时经常会用到最大化窗口,而如果此时是开着tomcat等服务的话,一段后台有打印什么东西出来都会自己弹出 console挺烦人的.可以使用以下操作关闭这个功能. Preferences ...

  2. Vue中使用vux的配置

    一.根据vux文档直接安装,无需手动配置 npm install vue-cli -g // 如果还没安装 vue init airyland/vux2 my-project // 创建名为 my-p ...

  3. this new call() apply()

    如果没接触过动态语言,以编译型语言的思维方式去理解javaScript将会有种神奇而怪异的感觉,因为意识上往往不可能的事偏偏就发生了,甚至觉得不可理喻.如果在学JavaScript这自由而变幻无穷的语 ...

  4. 12款jQuery幻灯片插件和幻灯片特效教程

    jQuery 使用简单灵活,同时还有许多成熟的插件可供选择,它可以帮助你在项目中加入一些非常好的效果.滑块和幻灯片效果是常用的内容展示方式之一,这是一种在有限的网页空间内展示系列项目时非常好的方法.今 ...

  5. LeetCode之数据流中第一个唯一的数字

    使用一个Map维护数字出现的次数,使用一个链表维护只出现一次的数,使用一个变量记录是否找到过终止数字. AC代码: public class Solution { /* * @param : a co ...

  6. linux内核sysfs详解【转】

    转自:http://blog.csdn.net/skyflying2012/article/details/11783847 "sysfs is a ram-based filesystem ...

  7. springMVC中ajax的实现

    function addDebtResult(){ var repayIds=$("#repayIds").val(); var lateFeeDay=$("#repay ...

  8. [转载]Windows服务编写原理及探讨(1)

    有那么一类应用程序,是能够为各种用户(包括本地用户和远程用户)所用的,拥有用户授权级进行管理的能力,并且不论用户是否物理的与正在运行该应用程序的计算机相连都能正常执行,这就是所谓的服务了. (一)服务 ...

  9. P1084 疫情控制

    Solution 二分答案, 尽量往上跳, 不能跳到根节点. 仍然能跳的拿出来.看剩下的点没有覆盖哪个? 贪心的分配一下. Code 70 #include<iostream> #incl ...

  10. npm install 装本地一直安装全局问题

    想用npm安装一些模块,不管怎么装,一直装作全局. 以为是node有问题,重装了N次,却还发现这个问题. 困惑几天无果, 偶然间通过此文章发现,npm存在配置文件:https://www.sitepo ...