Image upload
Hi Developers!
I have a problem with upload for pictures reflex does not have dynamic page reload. When a file with a photo is placed and saved in the database, it is dynamically added to the bottom of the page (for testing) and I noticed that when you add pictures, they are not displayed on the screen. But when you reload the server - everything is there. Agree, this is not convenient to add a gallery - you need to reload the page, which is not very convenient, especially if the project is already in operation. Tell me where my mistakes are?
Code:
from datetime import datetime
from sqlmodel import select, Field
from typing import Optional
import uuid
class Image(rx.Model, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
filename: str = Field(max_length=255)
caption: str = Field(max_length=500)
path: str = Field(max_length=255)
created_at: datetime = Field(default_factory=datetime.utcnow)
class State(rx.State):
"""The app state."""
images: list[Image] = []
caption: str = ""
processing: bool = False
progress: int = 0
def on_load(self):
"""Load existing images on page load."""
with rx.session() as session:
self.images = session.exec(
select(Image).order_by(Image.created_at.desc())
).all()
@rx.event
async def handle_upload_progress(self, progress: dict):
"""Handle upload progress updates."""
self.processing = True
self.progress = round(progress["progress"] * 100)
if self.progress >= 100:
self.processing = False
self.on_load()
@rx.event
async def handle_upload(self, files: list[rx.UploadFile]):
if not files or not self.caption:
return rx.window_alert("Please, add a caption for image")
for file in files:
file_extension = file.name.split('.')[-1]
unique_filename = f"{uuid.uuid4()}.{file_extension}"
upload_dir = rx.get_upload_dir()
outfile = upload_dir / unique_filename
upload_data = await file.read()
with outfile.open("wb") as file_object:
file_object.write(upload_data)
try:
file_url = f"/_upload/{unique_filename}"
with rx.session() as session:
db_image = Image(
filename=unique_filename,
caption=self.caption,
path=file_url
)
session.add(db_image)
session.commit()
session.refresh(db_image)
self.images = [db_image] + self.images
except Exception as e:
print(f"Database error: {e}")
return rx.window_alert("Error creating database entry.")
# Очищаем поле caption
self.caption = ""
# Перезагружаем список изображений
self.on_load()
def image_card(image: rx.Var[Image]):
return rx.vstack(
rx.image(
src=image.path,
height="200px",
width="auto",
),
rx.text(image.caption),
rx.moment(
image.created_at,
format="YYYY-MM-DD HH:mm:ss"
),
padding="5",
border="1px solid #eaeaea",
border_radius="md",
width="100%",
)
def index():
return rx.vstack(
rx.vstack(
rx.heading("Add new image"),
rx.text_area(
placeholder="Caption for image",
value=State.caption,
on_change=State.set_caption,
margin_bottom="5",
),
rx.upload(
rx.vstack(
rx.button(
"Выберите файл",
color="rgb(107,99,246)",
bg="white",
border="1px solid rgb(107,99,246)",
),
rx.text(
"upload image..."
),
),
id="upload1",
border="1px dotted rgb(107,99,246)",
padding="2em",
accept={
"image/png": [".png"],
"image/jpeg": [".jpg", ".jpeg"],
},
margin_bottom="5",
),
rx.hstack(
rx.foreach(
rx.selected_files("upload1"),
rx.text
)
),
rx.hstack(
rx.button(
"Upload",
on_click=State.handle_upload(
rx.upload_files(
upload_id="upload1",
on_upload_progress=State.handle_upload_progress,
)
),
),
rx.button(
"Clear",
on_click=rx.clear_selected_files("upload1"),
),
spacing="5",
),
rx.cond(
State.processing,
rx.vstack(
rx.text(f"Загрузка: {State.progress}%"),
rx.progress(value=State.progress, max=100),
),
),
padding="2em",
border="1px solid #eaeaea",
border_radius="10px",
width="100%",
margin_bottom="2em",
),
rx.heading("Gallery"),
rx.vstack(
rx.foreach(
State.images,
image_card,
),
spacing="5",
width="100%",
),
width="100%",
max_width="800px",
margin="0 auto",
padding="2em",
on_mount=State.on_load,
)
app = rx.App()
app.add_page(index, route="/")```
To start project:
reflex db init
reflex db makemigrations
reflex db migrate
reflex run
Hi! I'd like to work on this issue. Could you please assign it to me?
Hi! I'd like to work on this issue. Could you please assign it to me?
Hi! Yes, take this.
@AnonimPython Thank you so much for this opportunity. Can you provide a reference to this code block? It would be helpful.
@AnonimPython Thank you so much for this opportunity. Can you provide a reference to this code block? It would be helpful.
Yes! Ok, I will create a repo for u and give a link.
@AnonimPython I will be waiting for your response.