如何在Django-Rest-Framework中仅展示当前用户的视频?
问题描述
我正在使用Django和React开发一个YouTube克隆项目,拥有一个可让用户删除、编辑视频的管理面板。但目前面板会同时显示自身及其他用户的视频,请问如何实现仅展示当前用户视频的功能?
Django 后端代码(views.py)
class AdminVideoDetail(generics.RetrieveAPIView): permission_classes = [IsAuthenticated] queryset = Video.objects.all() serializer_class = VideoSerializer
React 前端组件(videos.js)
import React from 'react'; import { makeStyles } from '@material-ui/core/styles'; import Container from '@material-ui/core/Container'; import Link from '@material-ui/core/Link'; import Paper from '@material-ui/core/Paper'; import Table from '@material-ui/core/Table'; import TableBody from '@material-ui/core/TableBody'; import TableCell from '@material-ui/core/TableCell'; import TableContainer from '@material-ui/core/TableContainer'; import TableHead from '@material-ui/core/TableHead'; import TableRow from '@material-ui/core/TableRow'; import DeleteForeverIcon from '@material-ui/icons/DeleteForever'; import EditIcon from '@material-ui/icons/Edit'; import Button from '@material-ui/core/Button'; const useStyles = makeStyles((theme) => ({ cardMedia: { paddingTop: '56.25%', // 16:9 }, link: { margin: theme.spacing(1, 1.5), }, cardHeader: { backgroundColor: theme.palette.type === 'light' ? theme.palette.grey[200] : theme.palette.grey[700], }, videoTitle: { fontSize: '16px', textAlign: 'left', }, videoText: { display: 'flex', justifyContent: 'left', alignItems: 'baseline', fontSize: '12px', textAlign: 'left', marginBottom: theme.spacing(2), }, })); const Videos = (props) => { const { videos } = props; const classes = useStyles(); if (!videos || videos.length === 0) return <Button href={'/admin/create'} variant="contained" color="primary">New Video</Button>; return ( <React.Fragment> <Container maxWidth="md" component="main"> <Paper className={classes.root}> <TableContainer className={classes.container}> <Table stickyHeader aria-label="sticky table"> <TableHead> <TableRow> <TableCell>Id</TableCell> <TableCell align="left">Title</TableCell> <TableCell align="left">Action</TableCell> </TableRow> </TableHead> <TableBody> {videos.map((video) => { return ( <TableRow> <TableCell component="th" scope="row"> {video.id} </TableCell> <TableCell align="left"> <Link color="textPrimary" href={'/video/' + video.id} className={classes.link} > {video.title} </Link> </TableCell> <TableCell align="left"> <Link color="textPrimary" href={'/admin/edit/' + video.id} className={classes.link} > <EditIcon></EditIcon> </Link> <Link color="textPrimary" href={'/admin/delete/' + video.id} className={classes.link} > <DeleteForeverIcon></DeleteForeverIcon> </Link> </TableCell> </TableRow> ); })} <TableRow> <TableCell colSpan={4} align="right"> <Button href={'/admin/create'} variant="contained" color="primary" > New Video </Button> </TableCell> </TableRow> </TableBody> </Table> </TableContainer> </Paper> </Container> </React.Fragment> ); }; export default Videos;
解决方案
1. 确保Video模型关联用户
首先你的Video模型需要添加关联User的字段,用于记录视频所属用户:
from django.contrib.auth.models import User from django.db import models class Video(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="videos") title = models.CharField(max_length=255) # 其他视频字段(如视频文件、描述等)
2. 修改Django视图,过滤当前用户的视频
列表视图(管理面板获取视频列表用)
如果存在获取视频列表的视图(比如AdminVideoList),重写get_queryset方法只返回当前用户的视频:
from rest_framework import generics from .models import Video from .serializers import VideoSerializer from rest_framework.permissions import IsAuthenticated class AdminVideoList(generics.ListAPIView): permission_classes = [IsAuthenticated] serializer_class = VideoSerializer def get_queryset(self): # 仅返回当前登录用户的视频 return Video.objects.filter(user=self.request.user)
详情视图(AdminVideoDetail)
修改现有AdminVideoDetail,确保用户只能访问自己的视频,防止通过URL参数直接访问他人视频:
class AdminVideoDetail(generics.RetrieveAPIView): permission_classes = [IsAuthenticated] serializer_class = VideoSerializer def get_object(self): # 根据视频ID和当前用户过滤,找不到则返回404 obj = generics.get_object_or_404(Video, id=self.kwargs['pk'], user=self.request.user) self.check_object_permissions(self.request, obj) return obj
创建视频时自动关联用户
如果有创建视频的视图,保存时自动绑定当前登录用户:
class AdminVideoCreate(generics.CreateAPIView): permission_classes = [IsAuthenticated] serializer_class = VideoSerializer def perform_create(self, serializer): # 保存视频时设置所属用户为当前登录用户 serializer.save(user=self.request.user)
3. 前端无需额外修改
只要后端API返回的是当前用户的视频列表,你现有的videos.js组件可以直接使用,props.videos已经是过滤后的结果,只会渲染当前用户的视频。
内容的提问来源于stack exchange,提问作者PHILLIPP APETENOK
相关产品推荐
相关产品推荐

