renran-文章模块01

文章模块

创建子引用

cd renranapi/apps
python ../../manage.py startapp article

注册子应用

INSTALLED_APPS = [
	# ....
    'article',

]

模型代码

aricle./models.py,代码:

from django.db import models
from renranapi.utils.models import BaseModel
from users.models import User


# create your models here.
class ArticleCollection(BaseModel):
    """文集模型"""
    user = models.ForeignKey(User, on_delete=models.DO_NOTHING, verbose_name="用户")

    class Meta:
        db_table = "rr_article_collection"
        verbose_name = "文集"
        verbose_name_plural = verbose_name


class Special(BaseModel):
    """专题模型"""
    image = models.ImageField(null=True, blank=True, verbose_name="封面图片")
    notice = models.TextField(null=True, blank=True, verbose_name="专题公告")
    article_count = models.IntegerField(default=0, null=True, blank=True, verbose_name="文章总数")
    follow_count = models.IntegerField(default=0, null=True, blank=True, verbose_name="关注数量")
    user = models.ForeignKey(User, on_delete=models.DO_NOTHING, verbose_name="创建人")

    class Meta:
        db_table = "rr_special"
        verbose_name = "专题"
        verbose_name_plural = verbose_name


class Article(BaseModel):
    """文章模型"""
    content = models.TextField(null=True, blank=True, verbose_name="文章内容")
    html_content = models.TextField(null=True, blank=True, verbose_name="html内容")
    user = models.ForeignKey(User, on_delete=models.DO_NOTHING, verbose_name="作者")
    collection = models.ForeignKey(ArticleCollection, on_delete=models.CASCADE, verbose_name="文集ID")
    pub_date = models.DateTimeField(null=True, default=None, verbose_name="发布时间")
    access_pwd = models.CharField(max_length=15, null=True, blank=True, verbose_name="访问密码")
    read_count = models.IntegerField(default=0, null=True, blank=True, verbose_name="阅读量")
    like_count = models.IntegerField(default=0, null=True, blank=True, verbose_name="点赞量")
    collect_count = models.IntegerField(default=0, null=True, blank=True, verbose_name="收藏量")
    comment_count = models.IntegerField(default=0, null=True, blank=True, verbose_name="评论量")
    reward_count = models.IntegerField(default=0, null=True, blank=True, verbose_name="赞赏量")
    is_public = models.BooleanField(default=False, verbose_name="是否公开")

    class Meta:
        db_table = "rr_article"
        verbose_name = "文章"
        verbose_name_plural = verbose_name


class SpecialArticle(BaseModel):
    """文章和专题的绑定关系"""
    STATUS_OPTION = (
        (0, "未审核"),
        (1, "审核中"),
        (2, "审核通过"),
        (3, "审核不通过"),
    )
    article = models.ForeignKey(Article, on_delete=models.CASCADE, verbose_name="文章")
    special = models.ForeignKey(Special, on_delete=models.CASCADE, verbose_name="专题")
    status  = models.SmallIntegerField(choices=STATUS_OPTION, default=0, verbose_name="审核状态")
    user = models.ForeignKey(User,null=True,blank=True, on_delete=models.DO_NOTHING, verbose_name="审核管理员ID")
    
    class Meta:
        db_table = "rr_special_article"
        verbose_name = "专题的文章"
        verbose_name_plural = verbose_name


class SpecialManager(BaseModel):
    """专题管理员"""
    user = models.ForeignKey(User, on_delete=models.DO_NOTHING, verbose_name="管理员")
    special = models.ForeignKey(Special, on_delete=models.CASCADE, verbose_name="专题")

    class Meta:
        db_table = "rr_special_manager"
        verbose_name = "专题的管理员"
        verbose_name_plural = verbose_name


class SpecialFocus(BaseModel):
    """专题关注"""
    user = models.ForeignKey(User, on_delete=models.DO_NOTHING, verbose_name="管理员")
    special = models.ForeignKey(Special, on_delete=models.CASCADE, verbose_name="专题")

    class Meta:
        db_table = "rr_special_focus"
        verbose_name = "专题的关注"
        verbose_name_plural = verbose_name


class ArticleImage(BaseModel):
    """文章图片"""
    group = models.CharField(max_length=15, null=True, blank=True, verbose_name="组名")
    image = models.ImageField(null=True, blank=True, verbose_name="图片地址")

    class Meta:
        db_table = "rr_article_image"
        verbose_name = "文章图片"
        verbose_name_plural = verbose_name

数据迁移

python manage.py makemigrations
python manage.py migrate

相关依赖

在vue中引入集成markdown富文本编辑器

这里我们使用 mavonEditor,链接:https://github.com/hinesboy/mavonEditor

安装

cd renran_pc
npm install mavon-editor --save

在main.js中注册编辑器组件

    import mavonEditor from 'mavon-editor'
    import 'mavon-editor/dist/css/index.css'
	// 注册mavon-editor组件
    Vue.use(mavonEditor);

写文章页面

创建Writer.vue组件,提供给用户编写文章





路由代码:

// 。。。
import Write from "@/components/Writer"


export default new Router({
  mode: "history",
  routes: [
     // ....
      {
       name:"Writer",
       path:"/writer",
       component: Writer,
     },
  ]
})

在 Header.vue提供跳转链接

写文章

判断用户是否已经登录




settings.py,代码:

export default {
  Host:"http://api.renran.cn:8000", // ajax的服务端地址
  Website: "荏苒网",
  TC_captcha:{ // 防水墙验证码配置
    app_id: "2072894469",
  },
  check_user_login(vm,title="警告",content="您尚未登录!", confirm_text="跳转到首页", confirm_url="/"){
    // 验证用户是否已经登录了
    vm.token = localStorage.user_token || sessionStorage.user_token;
    if(vm.token){
      // 已经登录
      return vm.token;
    }else{
      // 没有登录
     vm.$confirm(content, title, {
        confirmButtonText: confirm_text,
        cancelButtonText: '返回上一页',
        type: 'warnning'
      }).then(() => {
        vm.$router.push(confirm_url);
      }).catch(() => {
        vm.$router.go(-1);
      });
    }
  }
}

显示当前登录用户的所有文集

视图,代码:

# Create your views here.

from rest_framework.generics import ListAPIView
from rest_framework.permissions import IsAuthenticated
from .models import ArticleCollection
from .serializers import CollectionModelSerializer
class CollecionListAPIView(ListAPIView):
    serializer_class = CollectionModelSerializer
    permission_classes = [IsAuthenticated]  # 必须是登陆用户才能访问过来

    def get_queryset(self):
        user = self.request.user
        ret = ArticleCollection.objects.filter(user=user).order_by("orders", "-id")
        if len(ret) < 1:
            # 如果没有文集, 给用户默认创建2个文集
            collection1 = ArticleCollection.objects.create(
                user=user,
                name="日记本",
                orders=1,
            )

            collection2 = ArticleCollection.objects.create(
                user=user,
                name="随笔",
                orders=2,
            )

            ret = [
                collection1,
                collection2,
            ]

        return ret

序列化器,代码:

from rest_framework import serializers
from .models import ArticleCollection
class CollectionModelSerializer(serializers.ModelSerializer):
    """文集序列化器"""
    class Meta:
        model = ArticleCollection
        fields = ["id","name"]

路由,代码:

from django.urls import path
from . import views
urlpatterns = [
    path("collection/", views.CollecionListAPIView.as_view()),
]

总路由,代码:

    path('article/', include("article.urls")),

客户端中展示所有文集,代码:



对于文集列表中的图标丢失,我们需要把 font-awesome 目录放到项目的static目录下即可。

添加文集

在原来文集列表的视图接口基础上,把CollectionListAPIView改成CollectionAPIView,代码:

# Create your views here.

from rest_framework.generics import ListAPIView
from rest_framework.permissions import IsAuthenticated
from .models import ArticleCollection
from .serializers import CollectionModelSerializer
from rest_framework.generics import CreateAPIView

class CollecionAPIView(ListAPIView,CreateAPIView):
    serializer_class = CollectionModelSerializer
    permission_classes = [IsAuthenticated]  # 必须是登陆用户才能访问过来

    def get_queryset(self):
        user = self.request.user
        ret = ArticleCollection.objects.filter(user=user).order_by("orders", "-id")
        if len(ret) < 1:
            # 如果没有文集, 给用户默认创建2个文集
            collection1 = ArticleCollection.objects.create(
                user=user,
                name="日记本",
                orders=1,
            )

            collection2 = ArticleCollection.objects.create(
                user=user,
                name="随笔",
                orders=2,
            )

            ret = [
                collection1,
                collection2,
            ]

        return ret

序列化器增加验证和create方法,代码:

from rest_framework import serializers
from .models import ArticleCollection
class CollectionModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = ArticleCollection
        fields = ["id","name"]

    def validate_name(self, name):
        """验证数据"""
        # 如果当前有用户曾经过同一个文集,则报错
        print(self.context) # 字典  {request:对象,view:对象,data_format: 字符串}
        user = self.context["request"].user
        try:
            ArticleCollection.objects.get(user=user,name=name)
            raise serializers.ValidationError("对不起, 当前文集名称已经被使用!~")
        except:
            pass

        return name

    def create(self, validated_data):
        """保存数据"""
        try:
            collection = ArticleCollection.objects.create(
                name=validated_data.get("name"),
                user=self.context["request"].user,
                orders=0,
            )
            return collection
        except:
            raise serializers.ValidationError("对不起, 添加文集失败!~")

路由代码调整:

from django.urls import path
from . import views
urlpatterns = [
    path("collection/", views.CollectionAPIView.as_view()),
]

客户端发起请求添加文集



控制文集菜单的显示隐藏[扩展]



删除文集[作业]

思路:

  1. 客户端根据current_collection来获取当前文集的id

  2. 通过ajax把文集id和jwt发送到服务端,服务端实现根据ID删除文集的操作

修改文集

文件的api视图新增集成UpdateAPIView,代码:

# Create your views here.

from rest_framework.generics import ListAPIView, CreateAPIView, UpdateAPIView
from rest_framework.permissions import IsAuthenticated
from .models import ArticleCollection
from .serializers import CollectionModelSerializer

class CollecionAPIView(ListAPIView,CreateAPIView, UpdateAPIView):
    serializer_class = CollectionModelSerializer
    permission_classes = [IsAuthenticated]  # 必须是登陆用户才能访问过来

    def get_queryset(self):
        user = self.request.user
        ret = ArticleCollection.objects.filter(user=user).order_by("orders", "-id")
        if len(ret) < 1:
            # 如果没有文集, 给用户默认创建2个文集
            collection1 = ArticleCollection.objects.create(
                user=user,
                name="日记本",
                orders=1,
            )

            collection2 = ArticleCollection.objects.create(
                user=user,
                name="随笔",
                orders=2,
            )

            ret = [
                collection1,
                collection2,
            ]

        return ret

序列化器,代码:

from rest_framework import serializers
from .models import ArticleCollection
class CollectionModelSerializer(serializers.ModelSerializer):
    """文集序列化器"""
    class Meta:
        model = ArticleCollection
        fields = ["id","name"]

    def validate_name(self, name):
        """验证数据"""
        # 如果当前有用户曾经过同一个文集,则报错
        # print(self.context)  # 字典  {request:对象,view:对象,data_format: 字符串}
        user = self.context["request"].user
        try:
            ArticleCollection.objects.get(user=user, name=name)
            raise serializers.ValidationError("对不起, 当前文集名称已经被使用!~")
        except:
            pass

        return name

    def create(self, validated_data):
        """添加数据"""
        try:
            collection = ArticleCollection.objects.create(
                name=validated_data.get("name"),
                user=self.context["request"].user,
                orders=0,
            )
            return collection
        except:
            raise serializers.ValidationError("对不起, 添加文集失败!~")

    def update(self, instance, validated_data):
        """更新数据"""
        instance.name = validated_data.get("name")
        instance.save()
        return instance

路由代码:

from django.urls import path,re_path
from . import views
urlpatterns = [
    path("collection/", views.CollecionAPIView.as_view()),
    re_path("^collection/(?P\d+)/$", views.CollecionAPIView.as_view()),
]

客户端使用ElementUI提供的弹窗,提供输入框给用户输入新的文集名称,并发送ajax提交数据到服务端。



你可能感兴趣的:(web)