项目作者: shreyashc

项目描述 :
REST API for social media (Blog) built using Django, Django-rest-framework, Postgres.
高级语言: Python
项目地址: git://github.com/shreyashc/social-media-blog-rest-api.git
创建时间: 2020-10-01T10:14:45Z
项目社区:https://github.com/shreyashc/social-media-blog-rest-api

开源协议:MIT License

下载


Social Media/ Blog REST API

(Django,drf,PostgreSQL)

live

https://hcblogapi.herokuapp.com/

Fully fledged rest api for social-media/blog
using Django and Django-rest-framework and
PostgreSQL(ORM).

features:

  • create,read,update,delete Blogs
  • user signup/login/password-update
  • comments
  • likes
  • Token Authentication
  • custom Admin pannel (/admin)
  • search filters
  • pagination
  • …..

TODO:

  • replace defatut tokens with JWTs

setup

  • db configuration

default(sqlLite)

  1. DATABASES = {
  2. 'default': {
  3. 'ENGINE': 'django.db.backends.sqlite3',
  4. 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
  5. }
  6. }

postgres

  1. DATABASES = {
  2. 'default': {
  3. 'ENGINE': 'django.db.backends.postgresql',
  4. 'NAME': 'dbname',
  5. 'USER': 'dbuser',
  6. 'PASSWORD': 'dbpassword',
  7. 'HOST': 'dbhost',
  8. 'PORT': '5432',
  9. }
  10. }

install

  1. pip install -r requirements.txt
  2. python manage.py migrate
  3. python manage.py runserver

CORS is disabled by default

ROUTES :

signup

  • /signup/
    • method : POST
  1. body
  2. {
  3. "username": REQUIRED
  4. "email": REQUIRED
  5. "password": REQUIRED
  6. "bio": OPTIONAL
  7. }
  8. //axios
  9. //request
  10. axios.post('BASE_URL/signup/',{
  11. username:'shreyas',
  12. email:'shreyas@gmail.com',
  13. password:'1@345*hc'
  14. })
  15. .then((res)=>{
  16. console.log(res.data)
  17. }).catch(err=>{
  18. console.log(err.response.data)
  19. })
  20. //response
  21. {
  22. username: 'shreyas',
  23. email: 'shreyas@gmail.com',
  24. token: '15892a7a87be9892f42db64b9ed76535c59a0b26'
  25. }
  26. //errors
  27. {
  28. username: [ 'This field is required.' ],
  29. email: [ 'This field is required.' ],
  30. password: [ 'This field is required.' ]
  31. },
  32. {
  33. username: [ 'username is already taken' ],
  34. email: [ 'email is already registred' ],
  35. password: [ 'Ensure this field has at least 8 characters.' ]
  36. }

login

  • /login/
    • method : POST
  1. //axios
  2. //request
  3. axios
  4. .post("BASE_URL/login/", {
  5. username: "shreyas",
  6. password: "1@345*hc",
  7. })
  8. .then((res) => {
  9. console.log(res.data);
  10. })
  11. .catch((err) => {
  12. console.log(err.response.data);
  13. });
  14. //response
  15. {
  16. id: 4,
  17. username: 'shreyas',
  18. email: 'shreyas@gmail.com',
  19. auth_token: 'e66628c5bb784e4b0c3366eecac938e18431ccbd'
  20. }
  21. //errors
  22. {
  23. username: [ 'This field is required.' ],
  24. password: [ 'This field is required.' ]
  25. },
  26. {
  27. [ 'Invalid username/password' ]
  28. }

update profile

  • /update-profile/
    • method : PUT / PATCH
    • Auth : REQUIRED
  1. //axios
  2. //request
  3. axios
  4. .patch(
  5. "BASE_URL/update-profile/",
  6. {
  7. email: "newEmail@gmail.com",
  8. bio: "bio update",
  9. },
  10. {
  11. headers: {
  12. //Token which you will get after login/signup
  13. Authorization: "Token e66628c5bb784e4b0c3366eecac938e18431ccbd",
  14. },
  15. }
  16. )
  17. .then((res) => {
  18. console.log(res.data);
  19. })
  20. .catch((err) => {
  21. console.log(err.response.data);
  22. });
  23. //reponse
  24. {
  25. message: 'Profile updated successfully',
  26. data: [ 'email:newEmail@gmail.com', 'bio:bio update' ]
  27. }
  28. //errors
  29. {
  30. //400
  31. email: [ 'Enter a valid email address.' ]
  32. },
  33. {
  34. //401
  35. detail: 'Authentication credentials were not provided.'
  36. }

change password

  • /change-password/
    • method : PUT / PATCH
    • Auth : REQUIRED
  1. //axios
  2. //request
  3. axios
  4. .patch(
  5. "BASE_URL/change-password/",
  6. {
  7. old_password: "1@345*hc",
  8. password1: "qwerty123",
  9. password2: "qwerty123",
  10. },
  11. {
  12. headers: {
  13. //Token which you will get after login/signup
  14. Authorization: "Token e66628c5bb784e4b0c3366eecac938e18431ccbd",
  15. },
  16. }
  17. )
  18. .then((res) => {
  19. console.log(res.data);
  20. })
  21. .catch((err) => {
  22. console.log(err.response.data);
  23. });
  24. //response
  25. {
  26. status: 'success',
  27. code: 200,
  28. message: 'Password updated successfully',
  29. data: []
  30. //Token remains the same.
  31. }
  32. //errors
  33. {
  34. old_password: [ 'This field is required.' ],
  35. password1: [ 'This field is required.' ],
  36. password2: [ 'This field is required.' ]
  37. },
  38. {
  39. password1: [ 'Ensure this field has at least 8 characters.' ],
  40. password2: [ 'Ensure this field has at least 8 characters.' ]
  41. },
  42. {
  43. old_password: [ 'incorrect password.' ]
  44. }

blogs

Get All Blogs

  • /blogs/
    • method : GET
  1. //fetchApi
  2. //request
  3. fetch('BASE_URL/blogs/', {
  4. method: 'GET',
  5. })
  6. .then(response => response.json())
  7. .then(data => console.log(data))
  8. .catch(err=>console.log(err))
  9. //axios
  10. //request
  11. axios
  12. .get("BASE_URL/blogs/")
  13. .then((res) => {
  14. console.log(res.data);
  15. })
  16. .catch((err) => {
  17. console.log(err.response.data);
  18. });
  19. //resopnse
  20. {
  21. count: 6,
  22. next: null,
  23. previous: null,
  24. results: [
  25. {
  26. id: 6,
  27. author: {
  28. "id": 1,
  29. "username": "shreyashc"
  30. },
  31. title: 'last blog2',
  32. category: 'pythonlkn',
  33. description: 'sdafdsfl;',
  34. content: 'sfdsafdskm',
  35. thumbnail: 'BASE_URL/media/images/blog_thumbnails/Untitled-1.psd',
  36. created_at: '2020-09-24T05:38:33.257468Z',
  37. no_of_likes: 0,
  38. no_of_comments: 0,
  39. comment: [],
  40. likes: []
  41. },
  42. {
  43. id: 5,
  44. author: {
  45. "id": 1,
  46. "username": "shreyashc"
  47. },
  48. title: 'last blog',
  49. category: 'python',
  50. description: 'sdafdsf',
  51. content: 'sfdsafds',
  52. thumbnail: 'BASE_URL/media/images/blog_thumbnails/Photo_20200607_153944.jpg',
  53. created_at: '2020-09-24T05:38:05.107503Z',
  54. no_of_likes: 0,
  55. no_of_comments: 0,
  56. comment: [],
  57. likes: []
  58. },
  59. ......
  60. ......
  61. ......

get a single blog

  • /blogs/:id (Int)
    • method : GET
  1. //fetchApi
  2. //request
  3. fetch('BASE_URL/blogs/2', {
  4. method: 'GET',
  5. })
  6. .then(response => response.json())
  7. .then(data => console.log(data))
  8. .catch(err=>console.log(err))
  9. //axios
  10. //request
  11. axios
  12. .get("BASE_URL/blogs/2")
  13. .then((res) => {
  14. console.log(res.data);
  15. })
  16. .catch((err) => {
  17. console.log(err.response.data);
  18. });
  19. //response
  20. {
  21. id: 2,
  22. author: {
  23. id: 2, username: 'manu'
  24. },
  25. title: 'Android',
  26. category: 'categeory test',
  27. description: 'this is a simple description',
  28. content: "this is content.",
  29. thumbnail: null,
  30. created_at: '2020-09-22T06:15:40.646519Z',
  31. no_of_likes: 2,
  32. no_of_comments: 1,
  33. comment: [
  34. {
  35. "id": 3,
  36. "text": "hello",
  37. "commented_by": {
  38. "id": 1,
  39. "username": "shreyashc"
  40. }
  41. }
  42. ],
  43. likes: [
  44. {
  45. "id": 2,
  46. "liked_by": {
  47. "id": 1,
  48. "username": "shreyashc"
  49. }
  50. },
  51. {
  52. "id": 3,
  53. "liked_by": {
  54. "id": 2,
  55. "username": "manu"
  56. }
  57. }
  58. ]
  59. }

create a blog

  • /blogs/
    • method : POST
    • Auth : REQUIRED
  1. //axios
  2. //request
  3. axios
  4. .post(
  5. "BASE_URL/blogs/",
  6. {
  7. title: "This is new blog.",
  8. description: "this is description",
  9. content: "content goes here",
  10. },
  11. {
  12. headers: {
  13. //Token which you will get after login/signup
  14. Authorization: "Token e66628c5bb784e4b0c3366eecac938e18431ccbd",
  15. },
  16. }
  17. )
  18. .then((res) => {
  19. console.log(res.data);
  20. })
  21. .catch((err) => {
  22. console.log(err.response.data);
  23. });
  24. //response
  25. {
  26. id: 7,
  27. author: { id: 4, username: 'shreyas' },
  28. title: 'This is new blog.',
  29. category: null,
  30. description: 'this is description',
  31. content: 'content goes here',
  32. thumbnail: null,
  33. created_at: '2020-09-26T06:05:45.786195Z',
  34. no_of_likes: 0,
  35. no_of_comments: 0,
  36. comment: [],
  37. likes: []
  38. }
  39. //errors
  40. {
  41. title: [ 'This field is required.' ],
  42. description: [ 'This field is required.' ]
  43. },
  44. {
  45. detail: 'Authentication credentials were not provided.'
  46. }

edit a blog

  • /blogs/:blog-id (Int)/
    • method : PUT/ PATCH
    • Auth : REQUIRED
  1. //axios
  2. //request
  3. axios
  4. .patch(
  5. "BASE_URL/blogs/7/",
  6. {
  7. title: "This is new blod has been editd.",
  8. category: "fun",
  9. },
  10. {
  11. headers: {
  12. //Token which you will get after login/signup
  13. Authorization: "Token e66628c5bb784e4b0c3366eecac938e18431ccbd",
  14. },
  15. }
  16. )
  17. .then((res) => {
  18. console.log(res.data);
  19. })
  20. .catch((err) => {
  21. console.log(err.response.data);
  22. });
  23. //response
  24. {
  25. id: 7,
  26. author: { id: 4, username: 'shreyas' },
  27. title: 'This is new blod has been editd.',
  28. category: 'fun',
  29. description: 'this is description',
  30. content: 'content goes here',
  31. thumbnail: null,
  32. created_at: '2020-09-26T06:05:45.786195Z',
  33. no_of_likes: 0,
  34. no_of_comments: 0,
  35. comment: [],
  36. likes: []
  37. }
  38. //errors
  39. {
  40. detail: 'Authentication credentials were not provided.'
  41. }

delete a blog

  • /blogs/:blog-id (Int)/
    • method : DELETE
    • Auth : REQUIRED
  1. //axios
  2. //request
  3. axios
  4. .delete(
  5. "BASE_URL/blogs/7/",
  6. {
  7. headers: {
  8. //Token which you will get after login/signup
  9. Authorization: "Token e66628c5bb784e4b0c3366eecac938e18431ccbd",
  10. },
  11. }
  12. )
  13. .then((res) => {
  14. console.log(res.data);
  15. })
  16. .catch((err) => {
  17. console.log(err.response.data);
  18. });
  19. //response
  20. 200;
  21. //errors
  22. {
  23. detail: "Authentication credentials were not provided.";
  24. }

like a blog

  • /likes/
    • method : POST
    • Auth : REQUIRED
  1. //axios
  2. //request
  3. axios
  4. .post(
  5. "BASE_URL/likes/",
  6. {
  7. post: 1,
  8. },
  9. {
  10. headers: {
  11. //Token which you will get after login/signup
  12. Authorization: "Token e66628c5bb784e4b0c3366eecac938e18431ccbd",
  13. },
  14. }
  15. )
  16. .then((res) => {
  17. console.log(res.data);
  18. })
  19. .catch((err) => {
  20. console.log(err.response.data);
  21. });
  22. //response
  23. {
  24. id: 7,
  25. post: 1,
  26. liked_by: 4,
  27. liked_at: '2020-09-26T06:20:08.152535Z'
  28. }
  29. //error
  30. {
  31. error: 'already liked'
  32. },
  33. {
  34. detail: "Authentication credentials were not provided.";
  35. }

remove like

  • /likes/:like-id (Int)/
    • method : POST
    • Auth : REQUIRED
  1. //axios
  2. //request
  3. axios
  4. .delete(
  5. "BASE_URL/likes/7",
  6. {
  7. headers: {
  8. //Token which you will get after login/signup
  9. Authorization: "Token e66628c5bb784e4b0c3366eecac938e18431ccbd",
  10. },
  11. }
  12. )
  13. .then((res) => {
  14. console.log(res.data);
  15. })
  16. .catch((err) => {
  17. console.log(err.response.data);
  18. });
  19. //response
  20. OK;
  21. //errors
  22. {
  23. detail: "Authentication credentials were not provided.";
  24. }

comment a blog

  • /comments/
    • method : POST
    • Auth : REQUIRED
  1. //axios
  2. //request
  3. axios
  4. .post(
  5. "BASE_URL/comments/",
  6. {
  7. post: 1,
  8. text: "nice post",
  9. },
  10. {
  11. headers: {
  12. //Token which you will get after login/signup
  13. Authorization: "Token e66628c5bb784e4b0c3366eecac938e18431ccbd",
  14. },
  15. }
  16. )
  17. .then((res) => {
  18. console.log(res.data);
  19. })
  20. .catch((err) => {
  21. console.log(err.response.data);
  22. });
  23. //response
  24. {
  25. id: 8,
  26. post: 1,
  27. text: 'nice post',
  28. commented_by: 4,
  29. commented_at: '2020-09-26T06:32:21.983423Z'
  30. }
  31. //errors
  32. {
  33. detail: "Authentication credentials were not provided.";
  34. }

edit comment

  • /comments/:comment-id(Int)/
    • method : PUT/PATCH
    • Auth : REQUIRED
  1. //axios
  2. //request
  3. axios
  4. .patch(
  5. "BASE_URL/comments/8/",
  6. {
  7. text: "nice post edited",
  8. },
  9. {
  10. headers: {
  11. //Token which you will get after login/signup
  12. Authorization: "Token e66628c5bb784e4b0c3366eecac938e18431ccbd",
  13. },
  14. }
  15. )
  16. .then((res) => {
  17. console.log(res.data);
  18. })
  19. .catch((err) => {
  20. console.log(err.response.data);
  21. });
  22. //response
  23. {
  24. id: 8,
  25. post: 1,
  26. text: 'nice post edited',
  27. commented_by: 4,
  28. commented_at: '2020-09-26T06:32:21.983423Z'
  29. }
  30. //errors
  31. {
  32. detail: "Authentication credentials were not provided.";
  33. }

remove comment

  • /comments/:comment-id(Int)/
    • method : PUT/PATCH
    • Auth : REQUIRED
  1. //axios
  2. //request
  3. axios
  4. .delete(
  5. "BASE_URL/comments/8/",
  6. {
  7. headers: {
  8. //Token which you will get after login/signup
  9. Authorization: "Token e66628c5bb784e4b0c3366eecac938e18431ccbd",
  10. },
  11. }
  12. )
  13. .then((res) => {
  14. console.log(res.data);
  15. })
  16. .catch((err) => {
  17. console.log(err.response.data);
  18. });
  19. //response
  20. OK;
  21. //errors
  22. {
  23. detail: "Authentication credentials were not provided.";
  24. }

user

get all users

  • /users/
    • method : GET
  1. //axios
  2. //request
  3. axios
  4. .get("BASE_URL/users/")
  5. .then((res) => {
  6. console.log(res.data);
  7. })
  8. .catch((err) => {
  9. console.log(err.response.data);
  10. });
  11. //response
  12. {
  13. count: 6,
  14. next: null,
  15. previous: null,
  16. results: [
  17. {
  18. id: 1,
  19. username: 'shreyashc',
  20. email: 'shreyashc@gmail.com',
  21. bio: null
  22. },
  23. {
  24. id: 2,
  25. username: 'manu',
  26. email: 'manu@gmail.com',
  27. bio: null
  28. },
  29. {
  30. id: 3,
  31. username: 'rahul',
  32. email: 'rahul@gmail.com',
  33. bio: null
  34. },
  35. {
  36. id: 4,
  37. username: 'shreyas',
  38. email: 'newEmail@gmail.com',
  39. bio: 'bio update'
  40. },
  41. {
  42. id: 5,
  43. username: 'shreyasf',
  44. email: 'shreyas@gmailf.com',
  45. bio: null
  46. },
  47. ...
  48. ...
  49. ...
  50. ]

get a single user

  • /users/user-id (Int)/
    • method : GET
  1. //axios
  2. //request
  3. axios
  4. .get("BASE_URL/users/3/")
  5. .then((res) => {
  6. console.log(res.data);
  7. })
  8. .catch((err) => {
  9. console.log(err.response.data);
  10. });
  11. //response
  12. {
  13. id: 3,
  14. username: "rahul",
  15. email: "rahul@gmail.com",
  16. bio: null,
  17. };

pagination

all responses are paginated by default

  1. {
  2. "count": 21,
  3. "next": "BASE_URL/comments/?page=2",
  4. "previous": null,
  5. "results": [res...]
  6. }
  • count = total results

  • next = next page

  • previous = previous page

  • you can use query param page=page_no get get a specific page.

search blogs

  • /search/?search=blog-title/
    • method : GET

search users

filter blogs by category

  • GET /blogs/?category=category-name

filter blogs by username

  • GET /blogs/?username=user-name

filter blogs by userId

  • GET /blogs/?username=user-id

additional info

Uploading image for thumbnail

  1. axios
  2. .post("BASE_URL/blogs/",
  3. {
  4. //form-data
  5. },
  6. {
  7. headers: {
  8. Authorization: "Token e66628c5bb784e4b0c3366eecac938e18431ccbd",
  9. Content-Type: "multipart/form-data"
  10. },
  11. })
  12. .then((res) => {
  13. console.log(res.data);
  14. })
  15. .catch((err) => {
  16. console.log(err.response.data);
  17. });