Upload Multiple files in Django 3 - python

I am new to pyhthon\Django and would like to get my Django 3 app to have the ability to upload multiple files but I am struggling to get this functionality, below is my sample code which uploads a single file, I beleive I need to enable multiple files in the forms.py and then override the post method to deal with multiple files.
As I bonus I would also like to use a field name from the form in the file path when it is saved.
(Pyhton 3.8/Django 3)
thanks
Model.py
class Predocs(models.Model):
doc_files = models.FileField(blank=True)
Form.py
from .models import Predocs
class PostForm(forms.ModelForm):
class Meta:
model = Predocs
fields = ['doc_files']
View.py
from django.shortcuts import render, redirect
# Create your views here.
from .forms import PostForm
from PredocsForm.models import Predocs
def create(request):
if request.method == 'POST':
form = PostForm(request.POST, request.FILES)
if form.is_valid():
# save form
form.save()
data = "test data"
return render(request, 'preform/created.html', {
'data': data
})
else:
form = PostForm()
return render(request,
'preform/create.html',
{
'form': form
})
def created(request):
return render(request, 'preform/created.html')

Related

"redirect" function of django is not working and after submitting the form, user remains on same page

In the function "createProject" of views.py, I want that after submitting the form user should redirect to the "projects" page.
But I don't know what is my mistake here. After submitting the form it does not redirect the user to "projects" page but remains on the same page.
"views.py" file:
from django.shortcuts import render, redirect
from django.http import HttpResponse
from .forms import ProjectForm
from .models import Project
def projects(request):
projects = Project.objects.all()
context = {'projects':projects}
return render(request, 'projects/projects.html', context)
def project(request, pk):
return render(request, 'projects/single-project.html')
def createProject(request):
form = ProjectForm()
if request.method == 'POST':
form = ProjectForm(request.POST)
if form.is_valid():
form.save()
redirect('projects')
context = {'form':form}
return render(request, 'projects/project_form.html', context)
Here is "urls.py" file:
from django.urls import path
from . import views
urlpatterns = [
path('', views.projects, name = 'projects'),
path('project/<str:pk>/', views.project, name = 'project'),
path('create-project/', views.createProject, name = 'create-project'),
]
Here is "project-form.html" [I am using Django "ModelForm"]:
from django.db.models.base import Model
from django.forms import ModelForm
from .models import Project
class ProjectForm(ModelForm):
class Meta:
model = Project
fields = ['title', 'description', 'demo_link', 'source_link', 'tags']
Can anyone help me in finding the mistake here ?
Why after submitting the form, it is not redirecting it to the "projects" page and remain on same page?
This issue is because the redirect response was never returned, so:
if form.is_valid():
form.save()
return redirect('projects')
# ^^^ Add this

Forms and views for custom User model with extra parameters [django 2.1]

Im trying to create a form that would allow me to add a profile picture to the custom User object. I know that there is OneToOne method, although I want it to be stored directly in User.
You need to extend default User Model like this:
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
"""Add more fields to default user model."""
profile_pic = models.ImageField(upload_to='profile_pics', blank=True, null=True)
Now you need to edit your settings.py to make your custom User model the default auth model. Add this line in your settings.py:
AUTH_USER_MODEL = 'myApp.User'
myApp is the name of app in whose models.py your created your Custom User Model.
And that's all, now the default auth model is your custom model User which is exactly the same as the Django default auth model except it has an additional field profile_pic to store an image.
Form to add picture should be like this:
class profilepictureForm(forms.ModelForm):
"""Form to add profile picture to User model."""
class Meta:
"""Meta class for profilepictureForm."""
model = User
fields = ('profile_pic', )
And in your views you should use this form like this:
def add_profile_picture(request):
if request.method == 'POST':
form = profilepictureForm(request.POST, request.FILES, instance=request.user)
if form.is_valid():
form.save()
return HttpResponseRedirect('/success/url/')
else:
form = profilepictureForm(instance=request.user)
return render(request, 'userpanel/profilepicture.html', {'form': form})
Have a look on below code
from django.http import HttpResponseRedirect
from django.shortcuts import render
from .forms import UploadFileForm
# Imaginary function to handle an uploaded file.
from somewhere import handle_uploaded_file
def upload_file(request):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
handle_uploaded_file(request.FILES['file'])
return HttpResponseRedirect('/success/url/')
else:
form = UploadFileForm()
return render(request, 'upload.html', {'form': form})
For more information please check https://docs.djangoproject.com/en/dev/topics/http/file-uploads/

Using an extended usermodel, how can I create two model instances with two modelforms in the same view?

First off, I want to say that I am new to django though I understand most of it, forms have always been confusing to me.
I have two models in which I need to create an instance from, the standard built in User model and my own UserProfile model.
The problem I am facing is that really do not know how to display two forms (one for each model) in the template and on save() then tell django that the newly created UserProfile instance's User = model.ForeignKey belongs to the also newly created User.
My forms.py is fairly simple:
from django import forms
from django.forms import ModelForm
from django.contrib.auth.models import User
from .models import UserProfile
class UserForm(ModelForm):
class Meta:
model = User
fields = ('username', 'email', 'password')
class UserProfileForm(ModelForm):
class Meta:
model = UserProfile
fields = ('display_name', 'avatar', 'birthday', 'usertype', 'daw', 'usergenre')
In my views.py I've tried doing this:
from .forms import UserForm
from .forms import UserProfileForm
# Create your views here.
def RegisterView(request):
if request.method == 'POST':
form = UserForm(request.POST)
form2 = UserProfileForm(request.POST)
if form.is_valid():
if form2.is_valid():
return HttpResponseRedirect('/login/')
return render(request, 'register.html', {'form': form, 'form2': form})
But when I try to access /register I get this error:
http://dpaste.com/19NH2A6
You should use save() method.
Next time you have a problem, check the official Django documentation.
ModelForms - save() method
from .forms import UserForm
from .forms import UserProfileForm
from django.http import HttpResponseRedirect
def RegisterView(request):
if request.method == 'POST':
form = UserForm(request.POST, prefix='uf')
form2 = UserProfileForm(request.POST, prefix='upf')
if form.is_valid():
if form2.is_valid():
form.save()
form2.save()
return HttpResponseRedirect('/login/')
elif request.method == 'GET':
form = UserForm(prefix='uf')
form2 = UserProfileForm(prefix='upf')
return render(request, 'register.html', {'form': form, 'form2': form2})
When you hit /register page from browser, your view gets GET request, you have created form only for POST request
from .forms import UserForm
from .forms import UserProfileForm
# Create your views here.
def RegisterView(request):
if request.method == 'POST':
form = UserForm(request.POST, prefix='uf')
form2 = UserProfileForm(request.POST, prefix='upf')
if form.is_valid():
if form2.is_valid():
return HttpResponseRedirect('/login/')
elif request.method == 'GET':
form = UserForm(prefix='uf')
form2 = UserProfileForm(prefix='upf')
return render(request, 'register.html', {'form': form, 'form2': form2})
You should read the traceback yourself so that you can find the error easily.
It says;
Exception Type: NameError at /register/
Exception Value: name 'HttpResponseRedirect' is not defined
You've used HttpResponseRedirect but you didn't import it, therefore it is not defined.
Add this to top of your code.
from django.http import HttpResponseRedirect

What is the appropriate way to set up a form and view in Django to accommodate both creating and updating a model

I am working with sensitive code and I am not able to share specifics based on rules at my job. However, I have a pretty specific issue that should be easy to help with without code. I am new to Django and I am using legacy code. My issue is that I need to build a form that will update an instance of the model if it already exists and if it does not exist, then the form will create and save a new instance of the model. Any suggestions or examples of what it might look like?
https://docs.djangoproject.com/en/dev/topics/forms/modelforms/
The only difference would be to pass the form an instance argument for existing objects.
myapp/models.py
from django.db import models
class Article(models.Model):
# Define fields here
myapp/forms.py
from django.forms import ModelForm
from myapp.models import Article
# Create the form class.
class ArticleForm(ModelForm):
class Meta:
model = Article
fields = ['pub_date', 'headline', 'content', 'reporter']
myapp/views.py
from django.core.urlresolvers import reverse
from django.shortcuts import render_to_response, redirect, get_object_or_404
from django.template import RequestContext
from myapp.models import Article
from myapp.forms improt ArticleForm
def create_entry(request):
if 'POST' == request.method:
form = ArticleForm(data=request.POST, files=request.FILES)
if form.is_valid():
obj = form.save()
return redirect('your-view')
else:
form = ArticleForm()
context = {'form': form}
render_to_response('myapp/create_entry.html', context, context_instance=RequestContext(request))
def edit_entry(request, article_id):
article = get_object_or_404(Article, pk=article_id)
if 'POST' == request.method:
form = ArticleForm(data=request.POST, files=request.FILES, instance=article)
if form.is_valid():
obj = form.save()
return redirect('your-view')
else:
form = ArticleForm(instance=article)
context = {'form': form}
render_to_response('myapp/edit_entry.html', context, context_instance=RequestContext(request))

Django model form not submitting correctly

I've created a model form which is then rendered in a context processor as the form is included on every page. Once the form is submitted it should re-direct to a 'thank you' page. However it just seems to re-load the page and remove the form. I had it all working when rendering on a page via a URL. Since moving the function to my context processor it doesn't redirect correctly.
It also saves the information that's provided into the model, in the admin. So I'm guessing it is something to do with redirect.
Here is my context processor:
from django.conf import settings
from contact_enquiries import forms
from django.shortcuts import render
from django.http import HttpResponseRedirect
def contact(request):
if request.method == 'POST':
form = forms.ContactUsForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('/thanks/')
else:
form = forms.ContactUsForm()
return {
'contact_form' : form,
}
forms.py
class ContactUsForm(ModelForm):
class Meta:
model = ContactUs
fields = ['name', 'contact_number', 'email', 'enquiry']
models.py
class ContactUs(models.Model):
name = models.CharField(max_length=200)
contact_number = models.IntegerField(max_length=50)
email = models.EmailField(max_length=300)
enquiry = models.TextField()
class Meta:
verbose_name_plural = "Contact Us"
def __unicode__(self):
return self.name
A context processor should always return a dictionary, it shouldn't return an http response.
One option is to make your contact form post to a different view. You do this by changing the action attribute of the form in your template.
<form action="{% url 'contact' %}" method="post">
Your contact view and url patterns would look something like this:
url('^/contact/$', contact, name="contact"),
def contact(request):
if request.method == 'POST':
form = forms.ContactUsForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('/thanks/')
else:
form = forms.ContactUsForm()
return render(request, "contact.html", {
'contact_form' : form,
})
Your context processor then simplifies to:
def contact(request):
form = forms.ContactUsForm()
return {'contact_form' : form}

Categories