项目源码下载:https://github.com/Cherish-sun/NEWS/tree/master
一、Models数据结构
二、创建模型 models.py
# Create your models here.
from django.db import models
import datetime
from django.contrib.auth.models import User
from DjangoUeditor.models import UEditorField
from django.db.models.signals import post_save
from django.dispatch import receiver
from rest_framework.authtoken.models import Token
class Category(models.Model):
title = models.CharField(max_length=20, verbose_name='名称', help_text="大类")
def __str__(self):
return self.title
class Meta:
ordering = ['title']
verbose_name = '新闻类别'
verbose_name_plural = verbose_name
class Item(models.Model):
title = models.CharField(max_length=20, verbose_name='名称', help_text="名称")
created_date = models.DateTimeField(default=datetime.datetime.now, verbose_name='创建时间', help_text="创建时间")
completed = models.BooleanField(default=False, verbose_name='是否完成', help_text="是否完成")
categorys = models.ForeignKey(Category, on_delete=models.CASCADE, related_name='items', help_text="大类")
def __str__(self):
return self.title
class Meta:
ordering = ['title']
verbose_name = '新闻子栏目'
verbose_name_plural = verbose_name
class Tag(models.Model):
name = models.CharField(max_length=50, verbose_name=u'名称', help_text="名称")
slug = models.SlugField(max_length=50, verbose_name=u'描述')
def __str__(self):
return self.name
class Meta:
ordering = ['id']
verbose_name = '标签'
verbose_name_plural = verbose_name
class Article(models.Model):
title = models.CharField(max_length=100, verbose_name='标题', help_text="名称")
slug = models.SlugField(unique_for_year='publish_date', verbose_name='描述')
# author = models.CharField(max_length=100, verbose_name='作者', help_text="作者")
author = models.ForeignKey(User, related_name='author', on_delete=models.CASCADE, verbose_name='作者', help_text="作者")
# content = models.TextField(verbose_name='内容')
content = UEditorField(u'内容', height=400, width=600, default='', imagePath="upload/",
toolbars='mini', filePath='upload/', blank=True)
status = models.CharField(max_length=2, verbose_name='状态', help_text="状态")
tags = models.ManyToManyField(Tag, related_name='tags', blank=True, help_text="标签")
publish_date = models.DateTimeField(default=datetime.datetime.now(), verbose_name='发布日期', help_text="发布日期")
expiration_date = models.DateTimeField(blank=True, null=True, verbose_name='有效日期', help_text="有效日期")
is_active = models.BooleanField(default=True, blank=True, verbose_name='是否热门', help_text="是否热门")
item = models.ForeignKey(Item, related_name='item', on_delete=models.CASCADE, verbose_name='类别名称', help_text="类别名称")
pic = models.ImageField(upload_to='uploads', verbose_name='图片', help_text="图片")
praise_num = models.IntegerField(default=0, verbose_name='点赞', help_text="点赞")
read_num = models.IntegerField(default=0, verbose_name='浏览数', help_text="浏览数")
fav_num = models.IntegerField(default=0, verbose_name='收藏数', help_text="收藏数")
def __str__(self):
return self.title
class Meta:
verbose_name = '新闻文章'
verbose_name_plural = verbose_name
class Ad(models.Model):
title = models.CharField(max_length=50, verbose_name='标题', help_text="标题")
pic = models.ImageField(upload_to='uploads', verbose_name='广告图', help_text="广告图")
adurl = models.URLField(verbose_name='地址', help_text="地址")
adlocation = models.CharField(max_length=2, verbose_name='位置', help_text="位置") # a1,a2,a3,b1,b2,b3....
status = models.CharField(max_length=1, default=1, verbose_name='状态', help_text="状态")
class UserFav(models.Model):
"""
用户收藏
"""
user = models.ForeignKey(User, related_name='user', on_delete=models.CASCADE, verbose_name="用户")
articles = models.ForeignKey(Article, related_name='articles', on_delete=models.CASCADE, verbose_name="文章",
help_text="文章id")
add_time = models.DateTimeField(default=datetime.datetime.now, verbose_name=u"添加时间")
class Meta:
verbose_name = '用户收藏'
verbose_name_plural = verbose_name
unique_together = ("user", "articles")
def __str__(self):
return self.user.username
按住Ctrl Alt l 快捷键可以将代码格式化
二、安装DjangoUeditor,富文本编辑器
下载地址:https://github.com/wsf31325909/DjangoUeditor
解压后,把DjangoUeditor文件夹拷贝到项目目录下面
注意:直接pip install DjangoUeditor的方法会出问题
settings.py中添加app
INSTALLED_APPS = [
'DjangoUeditor',
]
三、数据库迁移 , 打开pycharm底端Terminal依次输入以下迁移命令
python manage.py makemigrations # 迁移到我们数据库
python manage.py migrate # 同步到数据库
python manage.py createsuperuser # 创建超级用户, 根据提示输入用户名、邮箱、密码,用于django后台管理系统登陆
四、后台管理系统admin.py配置
from django.contrib import admin
from .models import *
# Register your models here.
class ArticleAdmin(admin.ModelAdmin):
# 列表显示字段
list_display = ('title', 'item', 'status', 'author', 'publish_date',
'expiration_date', 'is_active')
list_filter = ('author', 'status', 'is_active', 'publish_date',
'expiration_date')
# 每页记录数
list_per_page = 25
# 查询字段
search_fields = ('title', 'tags', 'slug', 'content')
class Media:
js = ('/static/ueditor/ueditor.config.js', '/static/ueditor/ueditor.all.min.js',)
class TagAdmin(admin.ModelAdmin):
list_display = ('name', 'article_count')
def article_count(self, obj):
return Article.objects.filter(tag=obj).count()
class CategoryAdmin(admin.ModelAdmin):
list_display = ('id', 'title', 'item_count')
def item_count(self, obj):
# return obj.item_set.count()
return Item.objects.filter(categorys=obj).count()
class ItemAdmin(admin.ModelAdmin):
list_display = ('title', 'created_date', 'categorys', 'completed')
class AdAdmin(admin.ModelAdmin):
list_display = ('title', 'pic', 'adurl', 'adlocation', 'status')
admin.site.register(Category, CategoryAdmin)
admin.site.register(Item, ItemAdmin)
admin.site.register(Tag, TagAdmin)
admin.site.register(Article, ArticleAdmin)
admin.site.register(Ad, AdAdmin)
这时运行程序,浏览器依次打开 http://127.0.0.1:8000/和http://127.0.0.1:8000/admin,如下图,说明以上配置成功,后台管理界面可以添加一些分类等测试数据
五、创建序列化器serializers
serializers是一个数据转换器,序列化主要是处理输入数据和输出数据(序列化输出、反序列化输入)
将复杂的数据结构与json或者xml这个格式互相转换
实例对象 <=> 原生数据类型 <=> JSON(XML)
User <=> b’{“name”: 1}’ <=> {“name”: 1}
• serializers有以下几个作用:
1、将queryset与model实例等进行序列化,转化成json格式,返回给用户(api接口)。
2、将post与patch/put的上来的数据进行验证。
3、对post与patch/put数据进行处理。
-
推荐用ModelSerializer继承了Serializer的相关功能,是对model实现序列化的封装(代码少)
序列化详细介绍:http://www.careeru.cn/blog/article/?id=85
进入article目录下创建serilaizes.py文件# -*- coding: utf-8 -*- """ @version: v1.0 @author: wyq @license: Apache Licence @contact: 976367613@qq.com @site: @software: PyCharm @file: serilaizes.py @time: 2019/3/1 16:48 """ from rest_framework import serializers from django.contrib.auth.models import User, Group from .models import Category, Item, Tag, Article, Ad, UserFav from rest_framework.validators import UniqueValidator, UniqueTogetherValidator # 序列化验证 from rest_framework.compat import authenticate # 权限验证 # user序列化类 继承ModelSerializer class UserSerializer(serializers.ModelSerializer): class Meta: # 指定模型名称 model = User # 指定需要字段,全部用"__all__" fields = "__all__" # fields = ('url', 'username', 'email', 'groups') class GroupSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = Group fields = ('url', 'name') # 分类 class CategorySerializer(serializers.ModelSerializer): class Meta: model = Category fields = "__all__" # 实现新闻类别增加类别下面的栏目数据,采用自定义字段方法实现 class CategoryitemsSerializer(serializers.ModelSerializer): # 通过SerializerMethodField增加新字段值 items = serializers.SerializerMethodField() class Meta: model = Category fields = "__all__" # 在序列化对象里添加自定义内容 函数名为:# 方法写法:get_ + 字段 def get_items(self, obj): items = Item.objects.filter(categorys=obj.id) if items: items_serializer = ItemnocateSerializer(items, many=True, context={'request': self.context['request']}) return items_serializer.data class CategoryStringSerializer(serializers.ModelSerializer): # 用__str__方法表示只读关系 items 为外键关系中的related_name items = serializers.StringRelatedField(many=True) class Meta: model = Category # fields = ('id', 'title','items') fields = "__all__" class CategoryPrimaryKeySerializer(serializers.ModelSerializer): # 用主键表示关系 items = serializers.PrimaryKeyRelatedField(many=True, read_only=True) class Meta: model = Category fields = "__all__" class CategorySlugSerializer(serializers.ModelSerializer): # 选取关系对象中任意一个字段(唯一标识)表示关系 items = serializers.SlugRelatedField( many=True, read_only=True, slug_field='title' ) class Meta: model = Category fields = "__all__" # 子栏目 class ItemSerializer(serializers.ModelSerializer): # 正向嵌套 categorys = CategorySerializer() class Meta: model = Item fields = "__all__" class ItemnocateSerializer(serializers.ModelSerializer): class Meta: model = Item fields = "__all__" # 按serializers来序列化 class TagSerializer(serializers.ModelSerializer): # id = serializers.Field() name = serializers.CharField(required=True, max_length=100) slug = serializers.CharField(required=True, max_length=100) class Meta: model = Tag fields = ('id', 'name', 'slug') class AdSerializer(serializers.ModelSerializer): class Meta: model = Ad fields = "__all__" class ArticleSerializer(serializers.ModelSerializer): # 外键相关对象 item = ItemSerializer() author = UserSerializer() tags = TagSerializer(many=True) class Meta: model = Article fields = "__all__" class Hot_articleSerializer(serializers.ModelSerializer): item = ItemSerializer() author = UserSerializer() tags = TagSerializer(many=True) class Meta: model = Article fields = "__all__" class ArticlemodelSerializer(serializers.ModelSerializer): class Meta: model = Article fields = "__all__" class UserDetailSerializer(serializers.ModelSerializer): """ 用户详情序列化类 """ token = serializers.CharField(required=False, max_length=1024) class Meta: model = User fields = "__all__" class UserRegSerializer(serializers.ModelSerializer): username = serializers.CharField(label="用户名", help_text="用户名", required=True, allow_blank=False, validators=[UniqueValidator(queryset=User.objects.all(), message="用户已经存在")]) password = serializers.CharField( style={'input_type': 'password'}, help_text="密码", label="密码", write_only=True, ) token = serializers.CharField(required=False, max_length=1024) class Meta: model = User fields = ('username', 'password', 'token') class UserLoginSerializer(serializers.ModelSerializer): """ 用户登录序列化类 """ username = serializers.CharField(required=True, max_length=100) password = serializers.CharField(required=True, max_length=100) token = serializers.CharField(required=False, max_length=1024) # attrs 为封装后的request def validate(self, attrs): username = attrs.get('username') password = attrs.get('password') if username and password: # 用户名称、密码登录验证 user = authenticate(request=self.context.get('request'), username=username, password=password) # The authenticate call simply returns None for is_active=False # users. (Assuming the default ModelBackend authentication # backend.) if not user: msg = '不能登录' raise serializers.ValidationError(msg, code='authorization') else: msg = '必须输入同时输入名称和密码' raise serializers.ValidationError(msg, code='authorization') attrs['user'] = user return attrs class Meta: model = User fields = ('id', 'username', 'password', 'token') class UserSetPasswordSerializer(serializers.ModelSerializer): username = serializers.CharField(label="用户名", help_text="用户名", required=True, allow_blank=False) password = serializers.CharField( style={'input_type': 'password'}, help_text="密码", label="密码", write_only=True, ) newpassword = serializers.CharField( style={'input_type': 'password'}, help_text="新密码", label="新密码", write_only=True, ) # 验证用户名、密码是否正确 def validate(self, attrs): username = attrs.get('username') password = attrs.get('password') if username and password: # 用户名称、密码登录验证 user = authenticate(request=self.context.get('request'), username=username, password=password) # The authenticate call simply returns None for is_active=False # users. (Assuming the default ModelBackend authentication # backend.) if not user: msg = '不能修改' raise serializers.ValidationError(msg, code='authorization') else: msg = '必须输入同时输入名称和密码' raise serializers.ValidationError(msg, code='authorization') attrs['user'] = user return attrs class Meta: model = User fields = ('username', 'password', 'newpassword') class UserFavDetailSerializer(serializers.ModelSerializer): articles = ArticleSerializer() class Meta: model = UserFav fields = ('articles', 'id') class UserFavSerializer(serializers.ModelSerializer): # 隐藏字段 user = serializers.HiddenField( default=serializers.CurrentUserDefault() ) class Meta: model = UserFav validators = [ UniqueTogetherValidator( queryset=UserFav.objects.all(), fields=('articles', 'user'), message="已经收藏" ) ] fields = ('user', 'articles', 'id')