how to upload multiple images properly - django

I have a simple model which has four different fileFields for uploading different files and images.
this is my models:
class DocumentInfo(models.Model):
id = models.AutoField(primary_key=True)
certificate = models.FileField(upload_to="documents", null=True)
id_card = models.FileField(upload_to="documents", null=True)
service_certificate = models.FileField(upload_to="documents", null=True)
educational_certificate = models.FileField(upload_to="documents", null=True)
users need to simply upload some images in four individual fields so, I created a simple form and passed it to views like this:
class DocumentForm(forms.ModelForm):
class Meta:
model = DocumentInfo
fields = ['certificate','id_card','service_certificate','educational_certificate']
views.py:
def document_info(request):
if request.method == 'POST':
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
form.instance.user = request.user
form.save()
return redirect('document')
if 'delete' in request.GET:
return delete_item(DocumentInfo, request.GET['id'])
else:
form = DocumentForm()
documents = DocumentInfo.objects.filter(user=request.user)
context = {
'form': form,
'documents': documents,
}
return render(request, 'reg/documents.html', context)
it works just fine at first but I cant reupload anything! the uploaded image neither gets saved the second time around nor deleted. what am I doing wrong?

try this.
views.py
def document_info(request):
documents = DocumentInfo.objects.filter(user=request.user).order_by('-pk')
if request.method == 'POST':
if documents:
form = DocumentForm(request.POST, request.FILES,instance=documents[0])
else:
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
if not documents:
form.instance.user = request.user
form.save()
return redirect('document')
else:
if documents:#if the user already has a document.
form = DocumentForm(instance=documents[0])
else:
form = DocumentForm()
context = {
'form': form,
'documents': documents,
}
return render(request, 'reg/documents.html', context)

Related

Django Form : after correctly submitting form I got this: "this field is required"

I've a category and I've added a form for user in each category.
So I've two fields to fill and after filling them correctly I submit but the page reload, and nothing appears in my DB... only one error on Image field: This field required. I don't really know what's wrong here.
class Picture(models.Model):
catego = models.ForeignKey(Catego,on_delete=models.CASCADE,related_name="catego_pictures")
user = models.ForeignKey(User, blank=True, null=True,on_delete=models.CASCADE,related_name='user_pictures')
image = models.ImageField(upload_to='nutriscore/')
pictureoption = models.CharField(max_length=20,choices=Pictureoption.choices,default=Pictureoption.HOME,)
publishing_date = models.DateField(auto_now_add=True)
class CreatePictureForm(forms.ModelForm):
def __init__(self,*args,**kwargs):
super(CreatePictureForm, self).__init__(*args,**kwargs)
self.helper = FormHelper()
self.helper.form_method="post"
self.helper.layout = Layout(
Field("image",css_class="single-input"),
Field("pictureoption",css_class="single-input"),
)
self.helper.add_input(Submit('submit','Upload a pic',css_class="single-input textinput textInput form-control"))
class Meta:
model = Picture
fields = [
'image',
'pictureoption',
]
def __str__(self):
return self.catego.name
views.py
#login_required(login_url='/cooker/login')
def catego(request, slug):
catego = Catego.objects.get(slug=slug)
context = {
'catego': catego
}
# if this is a POST request we need to process the form data
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = CreatePictureForm(request.POST)
# check whether it's valid:
if form.is_valid():
form.instance.catego = self.object
form.instance.user = self.request.user
form.save()
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
else:
form = CreatePictureForm()
context['form'] = form # add `form` to the context
return render(request, 'post_catego.html', context)
here is the answer
#login_required(login_url='/cooker/login')
def catego(request, slug):
catego = Catego.objects.get(slug=slug)
context = {
'catego': catego
}
# if this is a POST request we need to process the form data
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = CreatePictureForm(request.POST, request.FILES)
# check whether it's valid:
if form.is_valid():
form.instance.catego = catego
form.instance.user = request.user
form.save()
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
else:
form = CreatePictureForm()
context['form'] = form # add `form` to the context
return render(request, 'post_catego.html', context)

Django how to assign posts to user

I need to assign posts to user in Django. I created
user = models.ForeignKey('authentication.CustomUser', on_delete=models.CASCADE)
and then if I display this model in my form.html I have to choice one of all users, if I don't display user in my form.html the form's isn't save my views file :
def formularz(request):
form = DodajForm(request.POST)
if form.is_valid():
ogloszenie = form.save(commit=False)
ogloszenie.user = request.user
ogloszenie.save()
return redirect('atrakcje:after')
else:
ogloszenie = DodajForm()
context = {
'form': form,}
return render(request, 'formularz.html', context)
Can i please know how to resolve it?
Rewrite the form to exclude the user field:
class DodajForm(forms.ModelForm):
class Meta:
model = Dodaj
exclude = ['user']
In the view, you better alter the instance, and let the form do the save logic, since a ModelForm can also save many-to-many fields:
def formularz(request):
if request.method == 'POST':
form = DodajForm(request.POST, request.FILES)
if form.is_valid():
form.instance.user = request.user
form.save()
return redirect('atrakcje:after')
else:
ogloszenie = DodajForm()
context = {'form': form}
return render(request, 'formularz.html', context)

I am trying to edit the Django database but this error keeps happening:The view social.views.edit didn't return an HttpResponse object

This is my code for my view:
def edit(request):
if request.method == 'POST':
form = EditProfileForm(request.POST, instance=request.user)
else:
if form.is_valid():
user = form.save()
form = EditProfileForm(instance=request.user)
args = {'form': form}
return render(request, 'social/edit.html', args)
And here is the code for the form:
class EditProfileForm(UserChangeForm):
edit ='social/edit.html'
class Meta:
model = UserProfile
fields = ('description', 'image')
Here is the model:
class UserProfile(models.Model):
description = models.CharField(max_length=300, default=' ', blank=True)
image = models.ImageField(upload_to='profile_image', blank=True)
if you need any more information to help I would be more than gladly to give it to you
The problem is with the view function.
Every View must return some sort of response (HTTP Response in General)
you have an if else statement in your view if its a post it will just execute
form = EditProfileForm(request.POST, instance=request.user)
and then it doesn't return anything.
I think you have to do is,
For GET Request (when you visit the url, it has to render the form)
if request.method == 'GET':
form = EditProfileForm(instance=request.user)
args = {'form': form}
return render(request, 'social/edit.html', args)
For POST request (when you send POST to this view or different one)
if request.method == 'POST':
form = EditProfileForm(request.POST, instance=request.user)
if form.is_valid():
user = form.save()
# use render/redirect as needed. make sure it returns an HTTP Response
# note that render method also return HTTP Response
return HttpResponse('Done')
Make sure Form class is simply this
class EditProfileForm(UserChangeForm):
class Meta:
model = UserProfile
fields = ('description', 'image')

django ManyToManyField save [duplicate]

This question already has answers here:
Saving Many To Many data via a modelform in Django
(2 answers)
Closed 4 years ago.
There's form with many fields (Date, Char, Text, Image, URL...) and they works fine. I mean values are submitted to DB as they must. But when I added ManyToManyField, it didn't save the value of this MultipleChoice form to DB. Any ideas why?
models.py:
class EventTag(models.Model):
tags = models.CharField(max_length=300)
def __str__(self):
return self.tags
class Article(models.Model):
source = models.CharField(max_length=100)
source_img = models.ImageField(default='default.png', blank=True)
#other fields
event_tags = models.ManyToManyField(EventTag, blank=True)
forms.py:
class CreateArticle(forms.ModelForm):
class Meta:
model = models.Article
fields = ['source', 'source_img', 'event_tags', ]
views.py:
def article_create(request):
if request.method == 'POST':
form = forms.CreateArticle(request.POST, request.FILES)
if form.is_valid():
instance = form.save(commit=False)
instance.author = request.user
instance.save()
return redirect('articles:list')
else:
form = forms.CreateArticle()
return render(request, 'articles/article_create.html', { 'form': form })
after save your form you must call form.save_m2m(). your view must be like this:
def article_create(request):
if request.method == 'POST':
form = forms.CreateArticle(request.POST, request.FILES)
if form.is_valid():
instance = form.save(commit=False)
instance.author = request.user
instance.save()
form.save_m2m()
return redirect('articles:list')
else:
form = forms.CreateArticle()
return render(request, 'articles/article_create.html', { 'form': form })

Django/Python: How to change filename when saving file using models.FileField?

I found this example to upload a file using FileField and it works great.
https://simpleisbetterthancomplex.com/tutorial/2016/08/01/how-to-upload-files-with-django.html
Problem is that it saves the original filename of the file being uploaded. I don't want that. I can change the filename within models.py by overriding the save function (see below). For the life of me, I cannot figure out how to pass a filename in when I execute form.save() from views.py. I need to know the filename for another process. I thought about even returning a filename from the models.py save function. I'm a bit of a noob so forgive any missing details. I've searched this site and read loads of documentation, but I'm missing something. Any advice would be appreciated.
Forms.py
class DocumentForm(forms.ModelForm):
message = forms.CharField(widget=forms.Textarea(attrs={'rows': 5, 'cols': 50}))
class Meta:
model = Document
fields = ('description', 'document', )
Models.py
class Document(models.Model):
description = models.CharField(max_length=255, blank=True)
document = models.FileField(upload_to='atlasapp/documents/')
uploaded_at = models.DateTimeField(auto_now_add=True)
def save(self, *args, **kwargs):
randomNum = random.randint(10000,90000)
new_name = str(randomNum) + ".txt"
self.document.name = new_name
super(Document, self).save(*args, **kwargs)
Views.py
def model_form_upload(request):
if request.method == 'POST':
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return redirect('model_form_upload')
else:
form = DocumentForm()
return render(request, 'model_form_upload.html', {'form': form})
Could you perhaps call save() on the form with commit=False, set the name on the Document file, and then save the Document? For example:
def model_form_upload(request):
if request.method == 'POST':
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
document = form.save(commit=False)
document.name = 'some_new_name'
document.save()
return redirect('model_form_upload')
else:
form = DocumentForm()
return render(request, 'model_form_upload.html', {'form': form})