Update code to create posts

This commit is contained in:
2025-02-21 21:49:00 +11:00
parent 076f63bf8a
commit c238ed4cc4
5 changed files with 107 additions and 503 deletions
BIN
View File
Binary file not shown.
-2
View File
@@ -7,8 +7,6 @@ from . import api_views
# Create a router and register our viewsets with it
router = DefaultRouter(trailing_slash=False)
router.register('pages', page_views.PageViewSet, basename='api-pages')
# for API compatibility
router.register('newsletters', post_views.PostViewSet, basename='api-newsletters')
router.register('posts', post_views.PostViewSet, basename='api-posts')
router.register('music', api_views.MusicViewSet, basename='api-music')
+38 -2
View File
@@ -10,16 +10,52 @@ class PageSerializer(serializers.ModelSerializer):
'created_at', 'updated_at']
class PostSerializer(serializers.ModelSerializer):
tags = serializers.PrimaryKeyRelatedField(many=True, queryset=Tag.objects.all(), required=False)
tags = serializers.ListField(child=serializers.CharField(), required=False, write_only=True, help_text="List of tag slugs")
tag_details = serializers.SerializerMethodField(read_only=True)
class Meta:
model = Post
fields = ['id', 'title', 'content', 'tags', 'created_at', 'updated_at']
fields = ['id', 'title', 'content', 'tags', 'tag_details', 'created_at', 'updated_at']
read_only_fields = ['id', 'created_at', 'updated_at']
extra_kwargs = {
'title': {'required': True},
'content': {'required': True}
}
def get_tag_details(self, obj):
return [{'id': tag.id, 'name': tag.name, 'slug': tag.slug} for tag in obj.tags.all()]
def create(self, validated_data):
tag_slugs = validated_data.pop('tags', [])
post = Post.objects.create(**validated_data)
for tag_slug in tag_slugs:
try:
tag = Tag.objects.get(slug=tag_slug)
except Tag.DoesNotExist:
# If tag doesn't exist, create it with the slug as both name and slug
tag = Tag.objects.create(name=tag_slug, slug=tag_slug)
post.tags.add(tag)
return post
def update(self, instance, validated_data):
tag_slugs = validated_data.pop('tags', None)
for attr, value in validated_data.items():
setattr(instance, attr, value)
if tag_slugs is not None:
instance.tags.clear()
for tag_slug in tag_slugs:
try:
tag = Tag.objects.get(slug=tag_slug)
except Tag.DoesNotExist:
# If tag doesn't exist, create it with the slug as both name and slug
tag = Tag.objects.create(name=tag_slug, slug=tag_slug)
instance.tags.add(tag)
instance.save()
return instance
class ImageSerializer(serializers.ModelSerializer):
url = serializers.SerializerMethodField()
-453
View File
@@ -1,453 +0,0 @@
openapi: 3.1.0
info:
title: GoLinks API
description: API documentation for GoLinks service
version: 1.0.0
servers:
- url: http://localhost:8000
description: Local development server
paths:
/api/pages:
get:
summary: List all pages
description: Retrieve a paginated list of all pages
parameters:
- in: query
name: page
schema:
type: integer
description: Page number for pagination
- in: query
name: page_size
schema:
type: integer
description: Number of items per page
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/PageList'
post:
summary: Create a new page
description: Create a new page with the provided data
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/PageCreate'
responses:
'201':
description: Page created successfully
content:
application/json:
schema:
$ref: '#/components/schemas/Page'
/api/newsletters:
get:
summary: List all newsletters
description: Retrieve a paginated list of all newsletters
parameters:
- in: query
name: page
schema:
type: integer
description: Page number for pagination
- in: query
name: page_size
schema:
type: integer
description: Number of items per page
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/NewsletterList'
post:
summary: Create a new newsletter
description: Create a new newsletter with the provided data
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/NewsletterCreate'
responses:
'201':
description: Newsletter created successfully
content:
application/json:
schema:
$ref: '#/components/schemas/Newsletter'
/api/collections:
get:
summary: List all collections
description: Retrieve a paginated list of all image collections
parameters:
- in: query
name: page
schema:
type: integer
description: Page number for pagination
- in: query
name: page_size
schema:
type: integer
description: Number of items per page
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/CollectionList'
post:
summary: Create a new collection
description: Create a new image collection
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CollectionCreate'
responses:
'201':
description: Collection created successfully
content:
application/json:
schema:
$ref: '#/components/schemas/CollectionResponse'
/api/collections/{collection_id}:
delete:
summary: Delete a collection
description: Delete a collection and all its images
parameters:
- in: path
name: collection_id
required: true
schema:
type: string
format: uuid
description: The ID of the collection to delete
responses:
'200':
description: Collection deleted successfully
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessResponse'
/api/collections/{collection_id}/upload_images:
post:
summary: Upload images to a collection
description: Upload one or more images to a collection with optional descriptions
parameters:
- in: path
name: collection_id
required: true
schema:
type: string
format: uuid
description: The ID of the collection to upload images to
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
properties:
file:
type: array
items:
type: string
format: binary
description: List of image files to upload. Only image/* content types are allowed.
descriptions:
type: array
items:
type: string
description: Optional list of descriptions for the uploaded images. Each description corresponds to the image at the same index.
required:
- file
responses:
'201':
description: Images uploaded successfully
content:
application/json:
schema:
type: object
properties:
status:
type: string
enum: [success]
example: success
message:
type: string
example: "Successfully uploaded 2 images"
data:
type: array
items:
$ref: '#/components/schemas/Image'
'400':
description: Bad request - invalid file or upload failed
content:
application/json:
schema:
type: object
properties:
status:
type: string
enum: [error]
example: error
message:
type: string
example: "Invalid file type. Only images are allowed."
/api/images/{image_id}:
delete:
summary: Delete an image
description: Delete a specific image from a collection
parameters:
- in: path
name: image_id
required: true
schema:
type: string
format: uuid
description: The ID of the image to delete
responses:
'200':
description: Image deleted successfully
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessResponse'
components:
schemas:
Page:
type: object
properties:
id:
type: integer
url:
type: string
title:
type: string
summary:
type: string
content:
type: string
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
PageCreate:
type: object
required:
- url
- title
properties:
url:
type: string
title:
type: string
summary:
type: string
content:
type: string
PageList:
type: object
properties:
count:
type: integer
next:
type: string
nullable: true
previous:
type: string
nullable: true
results:
type: array
items:
$ref: '#/components/schemas/Page'
Newsletter:
type: object
properties:
id:
type: integer
title:
type: string
type:
type: string
enum: [technology, world_news]
content:
type: string
created_at:
type: string
format: date-time
NewsletterCreate:
type: object
required:
- title
- type
- content
properties:
title:
type: string
type:
type: string
enum: [technology, world_news]
content:
type: string
NewsletterList:
type: object
properties:
count:
type: integer
next:
type: string
nullable: true
previous:
type: string
nullable: true
results:
type: array
items:
$ref: '#/components/schemas/Newsletter'
Collection:
type: object
properties:
id:
type: string
format: uuid
name:
type: string
description:
type: string
image_count:
type: integer
created_at:
type: string
format: date-time
CollectionCreate:
type: object
required:
- name
properties:
name:
type: string
description:
type: string
CollectionList:
type: object
properties:
count:
type: integer
next:
type: string
nullable: true
previous:
type: string
nullable: true
results:
type: array
items:
$ref: '#/components/schemas/Collection'
CollectionResponse:
type: object
properties:
status:
type: string
enum: [success]
message:
type: string
data:
$ref: '#/components/schemas/Collection'
Image:
type: object
properties:
id:
type: string
format: uuid
collection:
type: string
format: uuid
title:
type: string
description: The original filename of the uploaded image
description:
type: string
nullable: true
description: Optional description for the image
file_key:
type: string
description: Internal storage key for the image
content_type:
type: string
description: MIME type of the image
example: "image/jpeg"
size:
type: integer
description: Size of the image in bytes
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
ImageUploadResponse:
type: object
properties:
status:
type: string
enum: [success]
message:
type: string
data:
type: array
items:
$ref: '#/components/schemas/Image'
SuccessResponse:
type: object
properties:
status:
type: string
enum: [success]
message:
type: string
ErrorResponse:
type: object
properties:
status:
type: string
enum: [error]
message:
type: string
+69 -46
View File
@@ -49,10 +49,10 @@ paths:
schema:
$ref: '#/components/schemas/Page'
/api/newsletters:
/api/posts:
get:
summary: List all newsletters
description: Retrieve a paginated list of all newsletters
summary: List all posts
description: Retrieve a paginated list of all posts
parameters:
- in: query
name: page
@@ -70,24 +70,24 @@ paths:
content:
application/json:
schema:
$ref: '#/components/schemas/NewsletterList'
$ref: '#/components/schemas/PostList'
post:
summary: Create a new newsletter
description: Create a new newsletter with the provided data
summary: Create a new post
description: Create a new post with the provided data
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/NewsletterCreate'
$ref: '#/components/schemas/PostCreate'
responses:
'201':
description: Newsletter created successfully
description: Post created successfully
content:
application/json:
schema:
$ref: '#/components/schemas/Newsletter'
$ref: '#/components/schemas/Post'
/api/collections:
get:
@@ -151,8 +151,8 @@ paths:
/api/collections/{collection_id}/upload_images:
post:
summary: Upload images to collection
description: Upload one or multiple images to a collection
summary: Upload images to a collection
description: Upload one or more images to a collection with optional descriptions
parameters:
- in: path
name: collection_id
@@ -160,7 +160,7 @@ paths:
schema:
type: string
format: uuid
description: The ID of the collection
description: The ID of the collection to upload images to
requestBody:
required: true
content:
@@ -173,13 +173,33 @@ paths:
items:
type: string
format: binary
description: List of image files to upload. Only image/* content types are allowed.
descriptions:
type: array
items:
type: string
description: Optional list of descriptions for the uploaded images. Each description corresponds to the image at the same index.
required:
- file
responses:
'201':
description: Images uploaded successfully
content:
application/json:
schema:
$ref: '#/components/schemas/ImageUploadResponse'
type: object
properties:
status:
type: string
enum: [success]
example: success
message:
type: string
example: "Successfully uploaded 2 images"
data:
type: array
items:
$ref: '#/components/schemas/Image'
/api/images/{image_id}:
delete:
@@ -254,38 +274,43 @@ components:
items:
$ref: '#/components/schemas/Page'
Newsletter:
Post:
type: object
properties:
id:
type: integer
title:
type: string
type:
type: string
enum: [technology, world_news]
content:
type: string
tag_details:
type: array
items:
$ref: '#/components/schemas/Tag'
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
NewsletterCreate:
PostCreate:
type: object
required:
- title
- type
- content
properties:
title:
type: string
type:
type: string
enum: [technology, world_news]
content:
type: string
tags:
type: array
items:
type: string
description: List of tag slugs to associate with the post
NewsletterList:
PostList:
type: object
properties:
count:
@@ -299,7 +324,19 @@ components:
results:
type: array
items:
$ref: '#/components/schemas/Newsletter'
$ref: '#/components/schemas/Post'
Tag:
type: object
properties:
id:
type: integer
name:
type: string
slug:
type: string
description:
type: string
Collection:
type: object
@@ -360,30 +397,25 @@ components:
id:
type: string
format: uuid
collection:
type: string
format: uuid
title:
type: string
description:
type: string
content_type:
type: string
size:
type: integer
url:
type: string
created_at:
type: string
format: date-time
ImageUploadResponse:
type: object
properties:
status:
updated_at:
type: string
enum: [success]
message:
format: date-time
url:
type: string
data:
type: array
items:
$ref: '#/components/schemas/Image'
SuccessResponse:
type: object
@@ -393,12 +425,3 @@ components:
enum: [success]
message:
type: string
ErrorResponse:
type: object
properties:
status:
type: string
enum: [error]
message:
type: string