Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is there a way to link each uploaded files with an other model by forgnekey or Abstract model? #62

Closed
c0d33py opened this issue Sep 28, 2021 · 4 comments

Comments

@c0d33py
Copy link

c0d33py commented Sep 28, 2021

Hello There,

I want to know how can i link each uploaded file with an post model like each post has multiple files(photos/videos). When the user click submit button the post is created and Each file get's uploaded along with it? In my case when the user click submit button The post is created but the files which are uploaded by the user are not getting post along with it. Would you like to guide me about working of function mantioned above? And do the needfull.

models.py

class StoredUpload(models.Model):
    post = models.ForeignKey(Post, on_delete=models.CASCADE, null=True) # This is the article model ForeignKey

    # The unique upload ID assigned to this file when it was originally
    upload_id = models.CharField(
        primary_key=True, max_length=22, validators=[MinLengthValidator(22)]
    )
    file = models.FileField(storage=DrfFilePondStoredStorage(), max_length=2048)
    uploaded = models.DateTimeField()
    stored = models.DateTimeField(auto_now_add=True)
    uploaded_by = models.ForeignKey(
        settings.AUTH_USER_MODEL, null=True, blank=True, on_delete=models.CASCADE
    )

views.py

class SubmitFormView(View):
    form_class = PostForm

    # Handle POST request
    def post(self, request):
        form = self.form_class(request.POST)
        if form.is_valid():
            post = form.save()

        # StoredUpload(post=post)  # did't get anything here!
        # Get the post request and extract the IDs of the temporary upload(s)
        # to be permanently stored.
        data = request.POST
        filepond_ids = data.getlist("filepond")
        stored_uploads = []
        for upload_id in filepond_ids:
            tu = TemporaryUpload.objects.get(upload_id=upload_id)
            store_upload(upload_id, os.path.join(upload_id, tu.upload_name))
            stored_uploads.append(upload_id)

        # Return the list of uploads that were stored.
        return HttpResponse(
            json.dumps({"status": "OK", "uploads": stored_uploads}),
            content_type="application/json",
        )
@jcohen02
Copy link
Collaborator

Hi @c0d33py, you asked:

When the user click submit button the post is created and Each file get's uploaded along with it?

When you drop a file onto the filepond user interface in your client (or when you click and select a file in the file chooser), the file is, by default, uploaded immediately and a TemporaryUpload object is created. An upload_id is generated on the server for this temporary upload and this upload_id is then returned to the client and stored in a hidden form field. I believe that if you add multiple files, multiple IDs are returned to the client and then stored in the form.

I know it's possible to turn off this immediate upload functionality in the filepond client, so that you have to trigger the form submission (e.g. by clicking a submit button) to upload the files - have you disabled immediate upload so that the files are only sent to the server when you click the submit button on your form?

Using the normal behaviour with immediate upload enabled, you would then subsequently submit your form after the files have already been uploaded and only the temporary upload IDs (+ any additional custom form content you've added) will be submitted to the server.

On the server side, you then get the list of IDs for the temporary uploads, e.g.:

filepond_ids = data.getlist('filepond')

...then you would move the original temporary uploads to stored uploads using something like this...

for upload_id in filepond_ids:
    tu = TemporaryUpload.objects.get(upload_id=upload_id)
    store_upload(upload_id, os.path.join(upload_id, tu.upload_name))

The call to store_upload creates a new StoredUpload object and deletes the original TemporaryUpload.

You can see an example of this with the advanced version of the tutorial. The corresponding server-side implementation is shown in this views.py example.

I hope I have correctly understood your question and that this helps but let me know if this is not clear and you're still having an issue with this.

@c0d33py
Copy link
Author

c0d33py commented Sep 28, 2021

First of all thanks @jcohen02 your reply! let me clear my question.

I don't want to turn off immediate upload functionality!
I want to upload Each file related with a post which i have created along with files. The Post model ForeignKey is also added into Storedupload model. i am also using advanced version of Djagno-drf-filepond. I just want to know about how can i pass the Post instance with StoredUpload object.

class StoredUpload(models.Model):
    post = models.ForeignKey(Post, on_delete=models.CASCADE, null=True)

@jcohen02
Copy link
Collaborator

jcohen02 commented Sep 29, 2021

Thanks for the further clarification. I think I understand the issue and can see a couple of different ways to resolve this...

Here's my understanding so far: You have a Post model. There is a web form where you capture the data that will be stored in a Post instance. There can be files uploaded in relation to a Post.

So, a user fills in the form on the web page and uploads one or more files. When the user adds the files, they are uploaded immediately and stored on the server side as TemporaryUpload instances by django-drf-filepond. The user then clicks a button to submit the form containing the information to be stored in the Post instance. (I think I originally got confused because when you were mentioning "post" I thought you were referring to an HTTP POST request!)

When the form is submitted, the Post is being created correctly but you're then having a problem to link this Post to each of your StoredUpload instances?

There is an issue here with the need to modify StoredUpload. For now, I think the following solution should work for you:

  • Use the store_upload function to store the uploaded file and then subsequently add the link to the Post object - based on the example code you provided above, I think that would look something like this:

    class SubmitFormView(View):
        form_class = PostForm
    
        # Handle POST request
        def post(self, request):
            form = self.form_class(request.POST)
            if form.is_valid():
                post = form.save()
    
            data = request.POST
            filepond_ids = data.getlist("filepond")
            stored_uploads = []
            for upload_id in filepond_ids:
                tu = TemporaryUpload.objects.get(upload_id=upload_id)
                su = store_upload(upload_id, os.path.join(upload_id, tu.upload_name))
                su.post = post
                su.save()
                stored_uploads.append(upload_id)
    
            # Return the list of uploads that were stored.
            return HttpResponse(
                json.dumps({"status": "OK", "uploads": stored_uploads}),
                content_type="application/json",
            )
    

More generally, I think a better solution that would save you from having to modify StoredUpload and would make updating to new versions of django-drf-filepond much easier would be to add support for extending StoredUpload. I'll look at adding this. Then you could create a new model class, something like class StoredUploadWithPost(django_drf_filepond.models.StoredUpload):. The store_upload call would then be modified with a new property to specify the use of a custom model and the ability to provide any additional properties. I'll open an issue to work on this.

I hope this helps you to resolve your issue but do let me know if you're still having a problem with this. Thanks for using django-drf-filepond.

@c0d33py
Copy link
Author

c0d33py commented Oct 2, 2021

Thanks a lot @jcohen02! This is what i want to do.

@c0d33py c0d33py closed this as completed Oct 2, 2021
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

No branches or pull requests

2 participants