Skip to content

Direct Attachment Uploads#48

Open
msc5 wants to merge 74 commits into
mainfrom
msc/direct-upload
Open

Direct Attachment Uploads#48
msc5 wants to merge 74 commits into
mainfrom
msc/direct-upload

Conversation

@msc5
Copy link
Copy Markdown

@msc5 msc5 commented Mar 3, 2026

No description provided.

@msc5 msc5 requested a review from zags March 3, 2026 14:54
@msc5 msc5 removed the request for review from zags March 3, 2026 15:42
@msc5 msc5 marked this pull request as ready for review March 3, 2026 21:09
@msc5 msc5 requested a review from zags March 3, 2026 21:09
Copy link
Copy Markdown

@gracewhitney gracewhitney left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bunch of comments, sorry 😬 many of them are not specific to file uploads, but since this is a reference codebase want to make sure we're keeping everything clean

Comment thread app/templates/app/dashboard.html Outdated
<div class="card-body">
<h3 class="card-title">All Attachments</h3>
<file-upload-dashboard
queryset_json="{{ attachments|escape }}"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎨 escape isn't doing anything here - it's already autoescaped. I don't think it's a good idea to inline the json as a param like this, though - won't the quotes in the json blob interfere with html parsing? It would be better to use json_script and provide an id to the element containing the JSON. Or, just populate async from an internal API path.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have experimented a little with using json_script in various places, and I agree it is better from a stability and security perspective, but I can't seem to find a good pattern to work with both this use case (rendering a list of attachments on the dashboard) and in the custom django form field case simultaneously. In the latter case, you really want to collocate the existing attachments context (in other cases, for instance in a Model multi-select widget, you'd want the serialized choices queryset), and if the form is within a vue app, vue will strip the <script> tags, and I haven't really found a good way to circumvent that. To that end, passing the context directly in props seems to be the cleanest and most django-like way to go.

I have cleaned up the passing of variables here though, I now directly consume the queryset json in the files vue model rather than using an intermediate variable, and i've removed the escape template tag (I agree I don't think that does anything here).

❓ Do you have any other ideas for a good pattern that achieves both of these goals?

Comment thread app/templates/app/dashboard.html
Comment thread app/templates/app/dashboard.html Outdated
Comment thread app/models.py
created_by = models.ForeignKey(User, related_name="sample_objects", on_delete=models.PROTECT)

# START_FEATURE direct_upload
attachments = models.ManyToManyField("Attachment", related_name="sample_objects")
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❓ Why is this a many to many instead of a FK? I suppose there could be a case for M2M but seems less likely, not that it particularly matters for the example

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code originates from DPU use-cases, and on that project MTM is very much preferred, not only in linking attachments but also in linking almost every other model. I would potentially be interested in implementing both methods (FK + MTM) since this is a reference/example implementation, if you think that would be useful

Comment thread app/serializers.py
model = Attachment
exclude = []

def to_representation(self, instance):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❓ Do you prefer overriding to_representation instead of using SerializerMethodField?

Copy link
Copy Markdown
Author

@msc5 msc5 Apr 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it depends on the situation, but in this case I think it would be much more verbose and provide no real benefits (its not like serializers are type-hinted anyways ☹️). What are your thoughts?

Edit: Actually if it is explicit, then drf-spectacular would be able to generate a better openAPI spec so that would be a decent benefit

Comment thread Dockerfile
# END_FEATURE vue
# ---------------------------------- Python ---------------------------------- #

FROM python:3.12.13-slim-trixie
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❓ Why change in base image?

Comment thread Dockerfile
" \
&& deps=" \
postgresql-client \
git \
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need git on the server? If you need it in a particular instance you can always install it, but doesn't seem necessary in general

Comment thread Dockerfile
# Copy application files and .env.example
COPY . /app/
COPY ./config/.env.example /app/config/.env
COPY .bashrc /root/
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❓ I don't see a .bashrc file in this codebase - won't this fail if not present?

Comment thread Dockerfile
CMD ["gunicorn", "--bind", ":8000", "--workers", "3", "config.wsgi:application"]
# END_FEATURE docker
EXPOSE 8080
CMD ["gunicorn", "--bind", ":8080", "--workers", "15", "config.wsgi:application"]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

15 workers? We're using 2 workers w/ 5 threads each.

Comment thread requirements.in
# END_FEATURE django_storages

# START_FEATURE direct_upload
boto3
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed if you replace the boto3 calls with default_storage calls. Also need to pip-compile

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants