How can I Show Only my Videos in Django-Rest-Framework? - reactjs

I'm using Django and React to create YouTube clone.
And I have an admin panel where user can delete and edit his videos.
But the problem is that it showing my videos and other users videos.
How can make that the admin panel will show only my videos?
views.py Api Views
class AdminVideoDetail(generics.RetrieveAPIView):
permission_classes = [IsAuthenticated]
quesryset = Video.objects.all()
serializer_class = VideoSerializer
videos.js Videos in the admin panel
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;
If you want to look at the whole project, here is github: https://github.com/PHILLyaHI/diplom-work

Create a python module named permissions.py
add these line of code
from rest_framework import permissions
class IsOwnerOrReadOnly(permissions.BasePermission):
"""
"""
def has_object_permission(self, request, view, obj):
# I check if the request is of type GET or OPTIONS
#I return true, that the use is able to access on this views
if request.method in permissions.SAFE_METHODS:
return True
return obj.owner == request.user
"""
Instance must have an attribute named `owner` or you can change owner with the name of your models fields `user = models.ForeignKey(UserModel, on_delete=models.casscade).
"""
After, go in your views.py module, add
class AdminVideoDetail(generics.RetrieveAPIView):
permission_classes = [IsAuthenticated, IsOwnerOrReadOnly]
quesryset = Video.objects.all()
serializer_class = VideoSerializer
Only videos of owner will be fetch

Related

MUI table Row collapse squashed into one cell when expanded and alignment error

Trying to use MUI table with Collapse to expand/collapse rows. However when using collapse, the the expanded rows are squashed into one cell. How can I align the expanded cells to the parent table cells in a material-ui table?
what i tried is on this link https://codesandbox.io/s/affectionate-leaf-lhb47z
CODE
import React, { useState } from "react";
import { makeStyles } from "#material-ui/core/styles";
import Grid from "#material-ui/core/Grid";
import Card from "#material-ui/core/Card";
import CardHeader from "#material-ui/core/CardHeader";
import Table from "#material-ui/core/Table";
import TableBody from "#material-ui/core/TableBody";
import TableCell from "#material-ui/core/TableCell";
import TableHead from "#material-ui/core/TableHead";
import TableRow from "#material-ui/core/TableRow";
import Paper from "#material-ui/core/Paper";
import TableContainer from "#material-ui/core/TableContainer";
import IconButton from "#material-ui/core/IconButton";
import KeyboardArrowDownIcon from "#material-ui/icons/KeyboardArrowDown";
import KeyboardArrowUpIcon from "#material-ui/icons/KeyboardArrowUp";
const useStyles = makeStyles((theme) => ({
header: {
backgroundColor: "white",
color: "#546e7a",
justifyContent: "left",
padding: "10px 0px",
fontWeight: "bold"
},
content: {
padding: 0
},
status: {
marginRight: "5px"
},
actions: {
justifyContent: "flex-end"
},
summaryTable: {
width: "auto",
marginBottom: "10px",
pointerEvents: "none"
},
noBorder: {
border: "none"
},
denseCell: {
padding: "5px"
},
formControl: {
margin: theme.spacing(1),
minWidth: 120
},
inputGroup: {
marginBottom: theme.spacing(1)
}
}));
const data1 = [
{
amount: 400.0,
dr_cr: "dr",
ledgerName: "Furniture"
},
{
amount: 10,
dr_cr: "dr",
ledgerName: "chocolate"
},
{
amount: 100.0,
dr_cr: "dr",
ledgerName: "goods purchase"
}
];
const data = [
{
amount: 510.0,
dr_cr: "dr",
ledgerName: "Assets"
},
{
amount: 5,
dr_cr: "cr",
ledgerName: "Liability"
}
];
const ExpandableTableRow = ({ children, expandComponent, ...otherProps }) => {
const [isExpanded, setIsExpanded] = React.useState(false);
return (
<>
<TableRow {...otherProps}>
<TableCell padding="checkbox">
<IconButton onClick={() => setIsExpanded(!isExpanded)}>
{isExpanded ? <KeyboardArrowUpIcon /> : <KeyboardArrowDownIcon />}
</IconButton>
</TableCell>
{children}
</TableRow>
{isExpanded && (
<TableRow>
<TableCell/>
{expandComponent}
</TableRow>
)}
</>
);
};
export default function App() {
const classes = useStyles();
const [records, setRecords] = useState(data || []);
const [records1, setRecords1] = useState(data1 || []);
return (
<div className="App">
<Grid item lg={12} md={12} xs={12}>
<Card>
<CardHeader
className={classes.header}
title={"Report"}
classes={{
title: classes.header
}}
/>
<Table stickyHeader>
<TableHead>
<TableRow>
<TableCell />
<TableCell>LedgerName</TableCell>
<TableCell>Debit</TableCell>
<TableCell>Credit</TableCell>
</TableRow>
</TableHead>
<TableBody>
{records.map((item) => (
<ExpandableTableRow
key={item.ledgerName}
expandComponent={
<Table>
<TableBody>
{records1.map((i) => (
<TableRow>
<TableCell>{i.ledgerName}</TableCell>
<TableCell>
{i.dr_cr === "dr" ? Math.round(i.amount, 2) : 0}
</TableCell>
<TableCell>
{i.dr_cr === "cr" ? Math.round(i.amount, 2) : 0}
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
}
>
<TableCell>{item.ledgerName}</TableCell>
<TableCell>
{item.dr_cr === "dr" ? Math.round(item.amount, 2) : 0}
</TableCell>
<TableCell>
{item.dr_cr === "cr" ? Math.round(item.amount, 2) : 0}
</TableCell>
</ExpandableTableRow>
))}
</TableBody>
</Table>
</Card>
</Grid>
</div>
);
}

React map() data not displaying

The data does not appear in the table in the view. Importing data from db was confirmed with the console.enter image description here
If it is simply used as list.map(), an error saying that it is not a function occurs. So list && list.length > 0 ? I am using list.map((e).
Or do I have to modify the const [list, setList] = useState code part?
import React, { useEffect, useState } from "react";
import axios from 'axios';
import Navbar from './Navbar';
import Box from '#mui/material/Box';
import Button from '#mui/material/Button';
import Table from '#mui/material/Table';
import TableBody from '#mui/material/TableBody';
import TableCell from '#mui/material/TableCell';
import TableContainer from '#mui/material/TableContainer';
import TableHead from '#mui/material/TableHead';
import TableRow from '#mui/material/TableRow';
import Paper from '#mui/material/Paper';
export default function Community() {
const [list, setList] = useState([{
inputData: {
post_id: '',
title: '',
writer: ''
},
}]);
useEffect(() => {
axios.get('http://localhost:5000/post/community').then((res) => {
console.log("성공");
console.log(res.data);
setList(res.data);
})
}, [])
return (
<div>
<Navbar />
<Box>
<Button sx={{ fontWeight: 'bold' }} href="/newpost">게시글 등록</Button>
</Box>
<TableContainer component={Paper}>
<Table aria-label="simple table">
<TableHead>
<TableRow>
<TableCell sx={{ fontWeight: 'bold' }}>Post_id</TableCell>
<TableCell sx={{ fontWeight: 'bold' }}>Title</TableCell>
<TableCell sx={{ fontWeight: 'bold' }} align="right">Writer</TableCell>
</TableRow>
</TableHead>
{list && list.length > 0 ? list.map((e) => {
return (
<TableBody>
<TableRow key={e.post_id}>
<TableCell component="th" scope="row">{e.post_id}</TableCell>
<TableCell align="right">{e.title}</TableCell>
<TableCell align="right">{e.writer}</TableCell>
</TableRow>
</TableBody>
)
}) : ""}
</Table>
</TableContainer>
</div>
);
}
Your first state is set up wrong which is then causing the map not to update the state data. It will only mutate not update.
Change
const [list, setList] = useState([{
inputData: {
post_id: '',
title: '',
writer: ''
},
}]);
To this
const [list, setList] = useState([])

Material-UI Warning: validateDOMNesting(...): <p> cannot appear as a descendant of <p>

I'm using Material UI and I get this error when I click on Collapse cmp (Material UI) which is inside a table:
validateDOMNesting(...): <p> cannot appear as a descendant of <p>. **
I saw same topic but with Typography which I didn't use.
I have no idea if the problem is the Collapse cmp or the element inside it
Here is the code:
import React from 'react'
import KeyboardArrowDownIcon from '#material-ui/icons/KeyboardArrowDown';
import KeyboardArrowUpIcon from '#material-ui/icons/KeyboardArrowUp';
import TableCell from '#material-ui/core/TableCell';
import TableRow from '#material-ui/core/TableRow';
import IconButton from '#material-ui/core/IconButton';
import Collapse from '#material-ui/core/Collapse';
import Box from '#material-ui/core/Box';
import classes from './post.module.scss'
import Button from '#material-ui/core/Button';
export default function PostRow(props) {
const { row, delatePost, loadProfile, fromProfile } = props;
const [open, setOpen] = React.useState(false);
return (
<React.Fragment>
<TableRow onClick={() => setOpen(!open)} style={{ borderBottom: 'unset', cursor: 'pointer' }}>
<TableCell>
עוד
<IconButton aria-label="expand row" size="small" onClick={() => setOpen(!open)}>
{open ? <KeyboardArrowUpIcon /> : <KeyboardArrowDownIcon />}
</IconButton>
</TableCell>
<TableCell align="right">{row.name}</TableCell>
<TableCell align="right" component="th" scope="row">
{row.businessField}
</TableCell>
<TableCell align="right">{row.followers}</TableCell>
</TableRow>
<TableRow>
<TableCell style={{ paddingBottom: 0, paddingTop: 0, }} colSpan={6}>
<Collapse in={open} timeout="auto" unmountOnExit>
<Box margin={0}>
<div className={classes.about}>
<h4>קצת על העסק</h4>
<p>{row.aboutBusiness}
<h4>דרישות</h4>
<p>{row.requirements}</p>
</p>
{fromProfile &&
<Button variant="contained" color="secondary" style={{marginBottom: '15px'}} onClick={async () => {
await delatePost(row._id)
loadProfile()
}}>מחק פוסט</Button>
}
</div>
</Box>
</Collapse>
</TableCell>
</TableRow>
</React.Fragment>
);
}
thanks guys i will read the articles :) meanwhile I just removed the P element and its working great.

Customize TableRow with Material UI component

I'm using Material UI table example and trying to customize the rows to have my own component to replace the default row.I want to have some margin between the rows and a shadow (using elevation prop of Paper element). This is what I achieved so far:
import React, { useState } from 'react'
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';
const MyPaper = (item) => {
return (
<Paper
elevation={6}>
{item}
</Paper>
);
};
const List = () => {
const items = ['a', 'b'];
return (
<div style={{ maxWidth: "100%" }}>
<TableContainer>
<Table aria-label="simple table">
<TableHead>
<TableRow>
<TableCell>Dessert (100g serving)</TableCell>
<TableCell align="right">Calories</TableCell>
<TableCell align="right">Fat (g)</TableCell>
<TableCell align="right">Carbs (g)</TableCell>
<TableCell align="right">Protein (g)</TableCell>
</TableRow>
</TableHead>
<TableBody>
{items.map(item => (
<TableRow key={item} component={() => MyPaper(item)}>
<TableCell>{item}</TableCell>
<TableCell>{item}</TableCell>
<TableCell>{item}</TableCell>
<TableCell>{item}</TableCell>
<TableCell>{item}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
</div>
)
}
export default List
but the result is being applied only in the first column. How do I fix this to have my custom row to occupy the entire table space?
Thanks in advance
You can do it easily with withstyles property of Material-UI, you can arrange Paper or other MUI components to give them classes and arrange them in styles variable:
import React, { useState } from 'react'
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 { WithStyles } from '#material-ui/core'
const styles = theme => ({
...theme,
Row: {
margin: 10
}
})
const List = () => {
const items = ['a', 'b'];
const {classes} = this.props
return (
<div style={{ maxWidth: "100%" }}>
<TableContainer>
<Table aria-label="simple table">
<TableHead>
<TableRow>
<TableCell>Dessert (100g serving)</TableCell>
<TableCell align="right">Calories</TableCell>
<TableCell align="right">Fat (g)</TableCell>
<TableCell align="right">Carbs (g)</TableCell>
<TableCell align="right">Protein (g)</TableCell>
</TableRow>
</TableHead>
<TableBody>
{items.map(item => (
<TableRow key={item} className={classes.Row}>
<TableCell>{item}</TableCell>
<TableCell>{item}</TableCell>
<TableCell>{item}</TableCell>
<TableCell>{item}</TableCell>
<TableCell>{item}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
</div>
)
}
export default withStyles(styles)(List)

Passing Arguments to Event Handlers

I'd be grateful if you could help me with my problem.
I've written a component to demonstrate the information of an array which includes both index.js and TableData.js files.Transferring the information of array from index.js to TableData in order to demonstrating them.
I passed the arguments to event handler correctly but I get an error. What's the problem with my code? In which part have I made a mistake?
App.js
import React, {Component, Fragment} from 'react';
import {TableData} from './Layouts'
class App extends Component {
state = {
productList: [
{id: 11, name: 'CD', price: '2000', describe: 'Educational'},
{id: 24, name: 'Pen', price: '3500', describe: 'Design'},
{id: 83, name: 'Pencil', price: '2500', describe: 'Design'}
],
};
handleDeleteByIndex = index => {
const product = this.state.productList;
product.splice(index, 1);
this.setState({productList: product});
};
render() {
const {productList} = this.state;
return (
<Fragment>
<TableData rows={productList} onDeleteRow={this.handleDeleteByIndex}/>
</Fragment>
);
}
}
export default App
TableData.js
import React from 'react';
import {makeStyles} from '#material-ui/core/styles';
import {
Table,
TableBody,
TableCell,
TableHead,
TableRow,
Paper
} from '#material-ui/core';
//****** Style CSS ******
const useStyles = makeStyles({
root: {
width: '100%',
overflowX: 'auto'
},
table: {
minWidth: 650
}
});
const test = 'right';
const TableData= (props) => {
const classes = useStyles();
return (
<Paper className={classes.root}>
<Table className={classes.table} aria-label="simple table">
<TableHead>
<TableRow>
<TableCell>Name Product</TableCell>
<TableCell align="right">Price</TableCell>
<TableCell align="right">Describe</TableCell>
</TableRow>
</TableHead>
<TableBody>
{props.rows.map((item, index) => (
<TableRow key={item.id}>
<TableCell component="th" scope="row">
{item.name}
</TableCell>
<TableCell align={test} data={item.name}>{item.price}</TableCell>
<TableCell align="right">{item.describe}</TableCell>
<TableCell align="right">
<button onClick={() => props.handleDeleteByIndex(index)}>
DEL
</button>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</Paper>
);
};
export default TableData
You are calling a function that does not exist. The passed down function in props is called onDeleteRow, not handleDeleteByIndex.
Just change it into:
onClick={() => props.onDeleteRow(index)}

Resources