Skip to content

Commit 03fbee4

Browse files
committed
created component and view for testing the upload image pipeline
1 parent b1d207c commit 03fbee4

File tree

6 files changed

+113
-3
lines changed

6 files changed

+113
-3
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import React, { useState } from "react";
2+
3+
const ImageUploader = () => {
4+
const [file, setFile] = useState<File | null>(null);
5+
const [status, setStatus] = useState<string>("");
6+
7+
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
8+
if (e.target.files && e.target.files[0]) {
9+
setFile(e.target.files[0]);
10+
}
11+
};
12+
13+
const handleUpload = async () => {
14+
if (!file) {
15+
setStatus("Please select a file to upload");
16+
return;
17+
}
18+
try {
19+
const formData = new FormData();
20+
formData.append("file", file);
21+
22+
const response = await fetch("/upload_image/", {
23+
method: "POST",
24+
body: formData
25+
});
26+
27+
if (!response.ok) {
28+
throw new Error("Failed to upload file");
29+
}
30+
31+
const data = await response.json();
32+
setStatus(`File uploaded successfully`);
33+
} catch (error) {
34+
setStatus(`Upload failed: ${(error as Error).message}`);
35+
}
36+
};
37+
return (
38+
<div>
39+
<h1>Image Upload Tester</h1>
40+
<input type="file" accept="image/*" onChange={handleFileChange} />
41+
<button onClick={handleUpload}>Upload</button>
42+
{status && <p>{status}</p>}
43+
</div>
44+
);
45+
};
46+
47+
export default ImageUploader;
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Generated by Django 4.2.7 on 2024-10-16 21:42
2+
3+
from django.db import migrations, models
4+
5+
import csm_web.settings
6+
7+
8+
class Migration(migrations.Migration):
9+
dependencies = [
10+
("scheduler", "0033_user_bio_user_pronouns_user_pronunciation"),
11+
]
12+
13+
operations = [
14+
migrations.AddField(
15+
model_name="user",
16+
name="profile_image",
17+
field=models.ImageField(
18+
blank=True, storage=csm_web.settings.ProfileImageStorage(), upload_to=""
19+
),
20+
),
21+
migrations.AlterField(
22+
model_name="user",
23+
name="bio",
24+
field=models.CharField(blank=True, default="", max_length=500),
25+
),
26+
migrations.AlterField(
27+
model_name="user",
28+
name="pronouns",
29+
field=models.CharField(blank=True, default="", max_length=20),
30+
),
31+
migrations.AlterField(
32+
model_name="user",
33+
name="pronunciation",
34+
field=models.CharField(blank=True, default="", max_length=50),
35+
),
36+
]

csm_web/scheduler/models.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,7 @@ class User(AbstractUser):
5555

5656
pronouns = models.CharField(max_length=20, default="", blank=True)
5757
pronunciation = models.CharField(max_length=50, default="", blank=True)
58-
# the upload_to field specifies subdivisions within S3 bucket
59-
profile_image = models.ImageField(storage=ProfileImageStorage())
58+
profile_image = models.ImageField(storage=ProfileImageStorage(), blank=True)
6059
bio = models.CharField(max_length=500, default="", blank=True)
6160

6261
def can_enroll_in_course(self, course, bypass_enrollment_time=False):

csm_web/scheduler/urls.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
path("user/", views.user_info, name="user"),
1919
path("user/<int:pk>/", views.user_retrieve, name="user_retrieve"),
2020
path("user/<int:pk>/update/", views.user_update, name="user_update"),
21+
path("user/<int:pk>/upload_image/", views.upload_image, name="2upload_image"),
2122
path("matcher/active/", views.matcher.active),
2223
path("matcher/<int:pk>/slots/", views.matcher.slots),
2324
path("matcher/<int:pk>/preferences/", views.matcher.preferences),

csm_web/scheduler/views/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,6 @@
66
from .section import SectionViewSet
77
from .spacetime import SpacetimeViewSet
88
from .student import StudentViewSet
9-
from .user import UserViewSet, user_info, user_retrieve, user_update
9+
10+
# from .test import upload_image
11+
from .user import UserViewSet, upload_image, user_info, user_retrieve, user_update

csm_web/scheduler/views/user.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,3 +139,28 @@ def user_info(request):
139139
"""
140140
serializer = UserSerializer(request.user)
141141
return Response(serializer.data, status=status.HTTP_200_OK)
142+
143+
144+
@api_view(["POST"])
145+
def upload_image(request, pk):
146+
"""
147+
Uploads an image to the aws s3 bucket
148+
"""
149+
150+
if "file" not in request.FILES:
151+
return Response(
152+
{"error": "No file was uploaded"}, status=status.HTTP_400_BAD_REQUEST
153+
)
154+
image = request.FILES["file"]
155+
156+
# use pk to get a User
157+
try:
158+
user = User.objects.get(pk=pk)
159+
except User.DoesNotExist:
160+
return Response({"detail": "Not found."}, status=status.HTTP_404_NOT_FOUND)
161+
162+
user.profile_image.save(image.name, image)
163+
164+
return Response(
165+
{"message": "File uploaded successfully"}, status=status.HTTP_200_OK
166+
)

0 commit comments

Comments
 (0)