Django views.py add multiple files - python

I have a model.py in which I would like to upload multiple files. In my models I have main class and another which I'm trying to use to upload multiple file as suggested. Problem is, I get the following error in my class in views.py 'Exception Value: Unknown field(s) (file) specified for Post' and I can't get it to upload multiple files.
model.py
class Post(models.Model):
title = models.CharField(max_length=40, verbose_name="Naslov predmeta")
# a lot more field here but not important
file_1 = models.FileField(blank=True, upload_to='PN_datoteke/%Y/%m/%d/', verbose_name="Datoteka 1", validators=[validate_file_size])
file_2 = models.FileField(blank=True, upload_to='PN_datoteke/%Y/%m/%d/', verbose_name="Datoteka 2", validators=[validate_file_size])
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post-detail', kwargs={'pk':self.pk})
class File(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE)
file = models.FileField(blank=True, upload_to='PN_datoteke/%Y/%m/%d/', verbose_name="Datoteke", validators=[validate_file_size])
views.py
class PostCreateView(LoginRequiredMixin, CreateView):
model = Post
fields = ['title', 'content_don', 'subject', 'rn_number', 'file_1', 'file_2']
def form_valid(self, form):
form.instance.author = self.request.user
#here I have a lot of code to process data which is writen in the fields
response = super(PostCreateView,self).form_valid(form)
#################################################################
##### this code below I'm trying to use to upload multiple files
obj = form.save(commit=False)
if self.request.FILES:
for f in self.request.FILES.getlist('file'):
obj = self.model.objects.create(file=f)
return response
I also tried using forms, but I can't get my scripts/querys and simmilar to work then. Is there a way to add file from class File in models to my views.py class and then use it to upload multiple fiels? Or is there a easier way?
forms.py
from django import forms
from .models import Post, File
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ['title', 'content_don', 'subject', 'rn_number', 'report_division', 'report_department', 'nc_type', 'number_res_people', 'res_person_1', 'res_person_2', 'res_person_3', 'res_person_4', 'urgency',
'date_days', 'cost_pn', 'cost_pn_tip', 'reklamacija', 'file_1', 'file_2', 'file_3', 'file_4']
class PostFileForm(PostForm): #extending form
file = forms.FileField(widget=forms.ClearableFileInput(attrs={'multiple': True}))
class Meta(PostForm.Meta):
fields = PostForm.Meta.fields + ['file',]
html template has a script to add multiple files upload option to my field, I'm not using widgets in forms.
<script>
$(document).ready(function(){
$('#id_file_1').attr("multiple","true");
})
</script>

Related

I have a problem in user redirecting in django

I am a beginner and I am creating a forum using html, css, bootstrap, python and django. I created a view for deleting posts:
class DeletePost(DeleteView):
model = Post
success_url = '/'
def get_queryset(self):
queryset = super().get_queryset()
return queryset.filter(author_post_id=self.request.user.id)
When a user will click the "Confirm button", when he need to remove a post, i would like to redirect him to the same discussion's page in which there was the post that he deleted, but i don't know how.
Can somebody help? Thanks in advance.
Post model:
class Post(models.Model):
post_author = ForeignKey(User, on_delete=models.CASCADE, related_name='posts')
content = models.TextField(default="Your content here...")
creation_date = DateTimeField(auto_now_add=True)
discussion = ForeignKey(Discussion, on_delete=models.CASCADE)
def __str__(self):
return self.post_author.username
class Meta:
verbose_name = 'Post'
verbose_name_plural = 'Posts'
Urls:
Discussion's url:
path('discussion/<int:pk>', views.view_discussion, name='view_discussion')
DeleteView's url:
path('discussion/<int:id>/delete_post/<int:pk>/', views.DeletePost.as_view(), name='delete_post')
You can override the get_success_url with:
class DeletePost(DeleteView):
model = Post
def get_queryset(self):
return super().get_queryset().filter(
author_post_id=self.request.user.id
)
def get_success_url(self):
return reverse('view_discussion', kwargs={'pk': self.object.discussion_id})
You can use the 'redirect' method in Django.
First import it: from django.shortcuts import redirect
then write this one line of code : return redirect('/nameOfURL') under your class/function based views.
Update :
def delete_post(request, id):
if request.method == 'POST':
pi = Post.objects.get(pk=id)
pi.delete()
return redirect('/view_discussion')

I can't get return super().form_valid(form) to work

I have resolved my issue and provided my solution below.
When I create or update a post the changes are saved to the sites database. But after clicking the submit button I get an error message.
No URL to redirect to. Either provide a url or define a get_absolute_url method on the Model.
I want to be redirected to the current URL. I thought the line of code return super().form_valid(form) implied that.
I could do success_url = '/'but I ideally don't want to be returned to the homepage.
class PostCreateView(LoginRequiredMixin, CreateView):
model = Post
fields = ['title', 'content']
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
The code in models.py was wrong, I was missing indents.
My site runs fine with this code -
class Post(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
date_posted = models.DateTimeField(default=timezone.now())
author = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post-detail', kwargs={'pk':self.pk})

Sending back file-content instead of href with django-rest-framework?

I have a model for articles which takes a field FileField which is supposed to be a markdown file for the user to load their article already. I expose the api with a ModelViewSet.
This is saved to my media folder. I could fetch the content from the client side by GETing it from the href of course but that would mean 2 requests to my server:
get article info (title, content- this is the md, date published, description, etc.. ).
get content from the link.
But i'm wondering if there's a way to tell django to just send the content of the file instead of the href when it responds to a requestion for the article item.
Here's my model and api:
# ---------------------- #
# src/articles/models.py #
# ---------------------- #
from os.path import splitext
from uuid import uuid4
from django.db import models
# Create your models here.
def hashFilename(instance, name):
ext = splitext(name)[1]
return "articles/{}{}".format(uuid4(), ext)
def hashImageFilename(instance, name):
ext = splitext(name)[1]
return "images/{}{}".format(uuid4(), ext)
class Article(models.Model):
title = models.CharField(("title"), max_length=100)
content = models.FileField("content", upload_to=hashFilename)
description = models.TextField(("description"), default='')
uploadDate = models.DateTimeField(("uploadDate"), auto_now=True)
lastModified = models.DateTimeField(("uploadDate"), auto_now=True)
publicationDate = models.DateField("publicationDate")
image = models.ImageField("image", upload_to=hashImageFilename)
def __str__(self):
return self.title
# ------------------------- #
# src/articles/api/views.py #
# ------------------------- #
from rest_framework.viewsets import ModelViewSet
from ..models import Article
from .serializers import ArticleSerializerFull, ArticleSerializerShort
class ArticlesViewSet(ModelViewSet):
queryset = Article.objects.all()
def get_serializer_class(self):
if self.action == 'list':
serializer = ArticleSerializerShort
else:
serializer = ArticleSerializerFull
return serializer
queryset = Article.objects.all()
Defining a serializers.SerializerMethodField--(DRF Doc) method will do the job.
class ArticleSerializer(serializers.ModelSerializer):
content = serializers.SerializerMethodField()
def get_content(self, article):
return article.content.file.read()
class Meta:
fields = '__all__'
model = Article
Alternatively, you could achieve the same by overriding the to_representation method of the serializer.
class ArticleSerializer(serializers.ModelSerializer):
class Meta:
fields = '__all__'
model = Article
def to_representation(self, instance):
rep = super().to_representation(instance)
rep['content'] = instance.content.file.read()
return rep
Update-1
From this comment, I hope you need a live markdown editor in Django Admin rather than a FileField.
So, Use any of these markdown packages to get a live view in the Django Admin. These packages are using models.TextField to store the markdown content. So that you could read the content from the field in anywhere just like any other model fields

Image upload in CreateView

I have a CreateView in my project to post a tweet-like-post. It has a title and content.
It look like this in views.py
class PostCreateView(LoginRequiredMixin, CreateView):
model = Post
fields = ['title', 'content']
def form_valid(self, form): # Author for post (required- if no- error)
form.instance.author = self.request.user
return super().form_valid(form)
And I would like to add picture-upload column to make a persons able to upload a picture with the post.
My models.py looks like this
class Post(models.Model):
title = models.CharField(max_length=100, verbose_name='タイトル')
content = models.TextField(verbose_name='内容')
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('Post-detail', kwargs={'pk': self.pk})
I already have a uploaded_pic folder in my static with 777 permision.
Could you please tell me how to add there working picture-upload column
picture_upload = models.ImageField()
If left as is it will upload to MEDIA_ROOT, which is recommended, but if you really want to modify that directory, you can use the upload_to property.
from django.conf import settings
picture_uploaded = models.ImageField(upload_to=settings.STATIC_URL + '/uploaded_pic')

User Specific Uploads Django 1.7

im getting this error "NOT NULL constraint failed: myfiles_document.user_id"
what im trying to do is attach files to user ForeignKey so user can only see what they upload im using this app django-file-form here the code for the project
model.py
class Example2(models.Model):
title = models.CharField(max_length=255)
class ExampleFile(models.Model):
fs = FileSystemStorage(location=settings.MEDIA_ROOT)
input_file = models.FileField(max_length=255, upload_to='uploads/%Y.%m.%d' , storage=fs)
user = models.ForeignKey('auth.User')
def get_upload_path(self,filename):
return "static/uploads/"+str(self.user.id)+"/"+filename
forms.py
class BaseForm(FileFormMixin, django_bootstrap3_form.BootstrapForm):
title = django_bootstrap3_form.CharField()
class MultipleFileExampleForm(BaseForm):
input_file = MultipleUploadedFileField()
def save(self):
example = Example2.objects.create(
title=self.cleaned_data['title']
)
for f in self.cleaned_data['input_file']:
ExampleFile.objects.create(
input_file=f
)
self.delete_temporary_files()
views.py
class BaseFormView(generic.FormView):
template_name = 'example_form.html'
def get_success_url(self):
return reverse('example_success')
def form_valid(self, form):
form.save()
return super(BaseFormView, self).form_valid(form)
class ExampleSuccessView(generic.TemplateView):
template_name = 'success.html'
class MultipleExampleView(LoginRequiredMixin, BaseFormView):
form_class = forms.MultipleFileExampleForm
Your foreign key will not be automatically set to the current user unless you do it manually. That's why you are getting the not-null constraint error. Try modifying your form_valid method like this:
def form_valid(self, form):
form.instance.user = self.request.user
...
Read Django's documentation on models and request.user for details.

Categories

Resources