Issues in uploading image from user without django ModelForm - html

I am trying to create a form without using ModelForm. I using the input elements in HTML for the purpose (to upload name and image). But I am having trouble uploading images with this process.
The name is getting saved but not the image.
My code:
models.py
class Register(models.Model):
name = models.CharField(max_length=50, null=True)
idCard = models.FileField(upload_to='idCard', null=True)
views.py
def index(request):
if request.method == 'POST':
data.name = request.POST.get('name')
data.idCard = request.POST.get('idCard')
data.save()
return redirect('/')
return render(request, 'event/index.html')
index.html
<form class="mform" id="myform" method="POST" id="myform" action="" enctype="multipart/form-data">
{% csrf_token %}
<fieldset>
<legend>Registeration</legend>
<table cellspacing="0"><tbody>
<tr><td>
<label for="u_name"> Username :</label></td><td>
<input type="text" name="name" id="u_name">
<td>
</tr>
<tr><td>
<label for="u_img"> IDCard :</label></td><td>
<input type='file' accept='image/*' onchange='openFile(event)' name="idCard" id="u_img">
</td></tr>
The name is getting saved but not the image.

The files are stored in request.FILES:
def index(request):
if request.method == 'POST':
data.name = request.POST.get('name')
data.idCard = request.FILES.get('idCard')
data.save()
return redirect('/')
return render(request, 'event/index.html')
That being said, I strongly advise to use a Form (or ModelForm). A form does not just handle saving the object, it also performs proper validation, can return error messages, and removes a lot of boilerplate code. Often with some tweaking, you can let the form look like you want. But even if you manually write the form in the template, you can still use a form at the Django level to validate and save the object.

Related

I am creating a django review system. I think my Html is wrong

I created the form and added it to view, how I must add it to html form?
index.html
<form action="." method="post">
{{ form.as_p }}
{% csrf_token %}
<p><input type="submit" value="Add comment"></p>
</form>
<h1 style="margin:0 57%">Reviews</h1>
<input type="hidden" name="parent" id="contactparent" value="">
<div class="dfv" style="display:flex; padding: 5%; justify-content: space-around; flex-wrap: wrap;align-items:center; box-shadow:4px 4px 16px gold;width: 80%;margin:8% 18% 0">
<div class="form-group editContent">
<label for="contactcomment" class="editContent" placeholder=" Message" >
Your reviews *
</label>
views.py
class AddReview(View):
"""Отзывы"""
def post(self, request,pk):
form = ReviewForm(request.POST,)
if form.is_valid():
form = form.save(commit=False)
#form.Dish = Dish
form.save()
review = Reviews.objects.all()
return render(request,'index.html',{'Reviews':review})
forms.py
class ReviewForm(ModelForm):
class Meta:
model = Reviews
fields = ('name', 'email', 'text')
urls.py
path("review/<int:pk>/", AddReview.as_view(), name='add_review'),
Request not found. Request URL: http://127.0.0.1:8000/%7Burl%20'add_review'%20dish.id%7D
enter code here
enter code here
Answer to the original question as to how to add the form to your HTML is to put the form into the context that is sent to the template:
{'form': form, 'Dish': dish, 'Snack': snack, 'Desserts': desserts, 'Lastcourses': lastcourses, 'Reviews': reviews}
Now for the rest. Here's what I had before you made all the changes to your code. The problem, I think is you're mixing function based views with class based views together in the same view. Second, you are handling either get or post when you need to handle both in the same view.
class DishView(View):
form_class = ReviewForm
template_name = 'index.html'
def get(self, request, *args, **kwargs):
form = self.form_class()
return render(request, self.template_name, {'form': form})
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
if form.is_valid():
form = form.save(commit=False)
form.name = request.name
form.text = request.text
form.save()
return redirect(self.path)
return render(request, self.template_name, {'form': form})
I also think you have an error in your form tag. If you want the form to be submitted back to the same view, then you don't use ".". You can leave the action out:
<form method="post">
<!-- OR -->
<form action="" method="post">

Using django Authentication form with the html form

I am trying to build a login module in django. I already have a nice HTML form for login which has username and password field.
But in my views.py I have imported default Django AuthenticationForm, but if integrate it with my nice-looking HTML form, there will be two forms. How can I import the Authentication form and use it with the my HTML form??
My code is here:
My view:
def login(request):
if request.method == 'POST':
form = AuthenticationForm(data=request.POST)
if form.is_valid():
user = form.get_user()
authlog(request, user)
return redirect('home')
else:
messages.error(request, 'Invalid username or password')
# back_page = request.META.get('HTTP_REFERER')
return redirect('login')
# return HttpResponse(back_page)
else:
content = {
'form': AuthenticationForm()
}
return render(request, 'sign-in.html', content)
If I use Django default form, the code will be following, but it won't look good as my other Html login page.
My sign-in html:
<hr>
<form action="" method="post">
{% csrf_token %}
{{form|crispy}}
<button type="submit" class=" btn btn-success ">Sign-Up</button>
</form>
I haven't posted my other HTML form though as it is very large. Hope it explains.

Is it possible to loop a custom model form in django?

Is it possible to create multiple objects for a model in django by looping the same form in a for loop. I am using a custom model form.
My template is:
{% for query in queryset %}
<form method="POST" action="{% url 'academics' %}" style=" padding: 5%">
{% csrf_token %}
<input type="text" name="Student" class="form-control" id="id_Student"
value="{{query}}">
<input type="text" name="Subject" class="form-control" required id="id_Subject">
<input type="checkbox" name="Presence" id="id_Presence">
<button type="Submit" id="submit">Submit</button>
{% endfor %}
<button type="Submit" id="submit">Submit</button>
</form>
My models.py is:
class Attendance(models.Model):
Student = models.CharField(max_length=100, blank=False)
Hour = models.CharField(max_length=1, blank=False)
Subject = models.CharField(max_length=8, blank=False)
Date = models.DateTimeField(default=timezone.now)
Presence = models.BooleanField(default=False, blank=False)
def __str__(self):
return f'{self.Student}'
My views.py is:
def academics(request):
if request.user.is_staff:
form = forms.AttendanceForm()
context = {
'form': form,
'queryset': User.objects.filter(profile__Year='SY',profile__Department='CSE')
}
if request.method == "POST" :
form = forms.AttendanceForm(request.POST)
if form.is_valid():
student = request.POST.get('Student')
hour = request.POST.get('Hour')
subject = request.POST.get('Subject')
boolean = request.POST.get('Presence')
def bool(boolean):
if boolean == 'on':
return 'True'
else:
return 'False'
form = Attendance(Student=student,Hour=hour,Subject=subject,Presence=bool(boolean))
form.save()
return render(request, 'console/academics.html',context)
Currently i can create multiple objects, but with the same values of the last form. ie, the object is created with the values of last form. Here i have looped the form so that n number of forms will be generated for n queries with the name filled automatically in the first field. I know explaining this is little complex. Anyone can help?
I'm not entirely clear what you mean by "looping a form", but if you want the user to be able to enter a list of arbitrary length of similar sets of data, then what you want is a Formset or a ModelFormset. When it comes back, you validate all the data that he has submitted, and if it's all good then you iterate through it, usually creating or modifying multiple objects.
Due to reputation I'm unable to comment but I believe this is how you achieve your desired result. by using WHILE LOOP.
I myself have not much knowledge of python & Django but I guess this is the logic. Please correct me if I am wrong instead of down voting.
var = 0
n = 5
if request.method == "POST":
form = forms.AttendanceForm(request.POST)
if form.is_valid():
while var < n:
student = request.POST.get('Student')
hour = request.POST.get('Hour')
subject = request.POST.get('Subject')
boolean = request.POST.get('Presence')
def bool(boolean):
if boolean == 'on':
return 'True'
else:
return 'False'
form = Attendance(Student=student, Hour=hour,Subject=subject,Presence=bool(boolean))
form.save()
var += 1
return render(request, 'console/academics.html', context)

Invalid form when uploading file in Django

I need to upload file on a Django page, however, after following the official tutorial, I was not able to upload it, it always gives the error "invalid form", and when I tried to print out the error msg of the form, it says "This field is required".
One thing notable is: I have 2 forms on one page, one is this upload form and the other one is for filling out information. Not sure if this is the root cause.
I have tried all solutions provided on the Internet.
Template file:
<form id="uploadForm" action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<input type="file" value="upload" name="sourcefile">
<button type="submit">Upload</button>
</form>
Forms.py:
from django import forms
from .models import SourceFile
class UploadFileForm(forms.ModelForm):
class Meta:
model = SourceFile
fields = ('file', 'title')
Models.py:
from django.db import models
# Create your models here.
class SourceFile(models.Model):
title = models.CharField(max_length=255, blank=True)
file = models.FileField(upload_to="media/")
Views.py
def model_form_upload(request):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
instance = SourceFile(file_field=request.FILES['file'])
instance.save()
return JsonResponse({'error': False, 'message': 'Uploaded Successfully!'})
else:
print("Invalid form")
# return JsonResponse({'error': True, 'errors': form.errors})
else:
form = UploadFileForm()
return render(request, 'source_validation.html', {'form': form})
Your template is wrong. Either use {{ form.as_p }} which should display a file input field because file is a field in your form. (so remove the <input type="file" ...>)
Or don't use it and manually add the <input> fields, but then you must use the correct names. Your form expects a "file" parameter, not a "sourcefile" parameter:
<input type="file" name="file">
Also, you're overcomplicating things in your view (even though your current code will work if you fix your template):
if form.is_valid():
form.save() # this will save your model
return redirect(...)

Django upload form with different models

I am building my first Django app and I need to have an upload page where I would be able to upload multiple files in different upload forms. I need different forms and, I guess, models since depending on the form the file has to be stored in a respective folder in my media root and go through different further transformations. I also want different users have different levels of access to these uploads.
So far I have something like this (I have quite a bit of additional code inside functions in views.py that send data to data frames or other programs but I am not posting those:
models.py
class Upload(models.Model):
document = models.FileField(storage=OverwriteStorage(),upload_to=get_file_path)
upload_date=models.DateTimeField(auto_now_add =True)
class Upload_variables(models.Model):
variables = models.FileField(storage=OverwriteStorage(),upload_to=get_file_path_var)
upload_date=models.DateTimeField(auto_now_add =True)
forms.py
from django import forms
from uploader.models import Upload, Upload_variables
class UploadForm(forms.ModelForm):
class Meta:
model = Upload
fields = ('document',)
class UploadFormVar(forms.ModelForm):
class Meta:
model = Upload_variables
fields = ('variables',)
views.py
def home(request):
if request.method=="POST":
img = UploadForm(request.POST, request.FILES)
if img.is_valid():
img.save()
else:
img=UploadForm()
files=Upload.objects.all()
return render(request,'home.html',{'form':img})
def variables(request):
if request.method == 'POST':
var = UploadFormVar(request.POST, request.FILES)
if var.is_valid():
var.save()
else:
var = UploadFormVar()
files_st = Upload_variables.objects.all()
return render(request, 'home.html', {'form_b': var})
HTML
<form action="#" method="post" enctype="multipart/form-data">
{% csrf_token %} {{form}}
<input type="submit" value="Upload" id="submit_form"/>
</form>
<form action="#" method="post" enctype="multipart/form-data">
{% csrf_token %} {{form_b}}
<input type="submit" value="Upload" id="staging"/>
</form>
So I can see 2 Upload buttons but only one 'choose file'....
Thank you for your help!
Currently you are placing the forms in two separate views. You need to put them in the same view like this:
def home(request):
if request.method=="POST":
var = UploadFormVar(request.POST, request.FILES)
img = UploadForm(request.POST, request.FILES)
if img.is_valid():
img.save()
if var.is_valid():
var.save()
else:
img = UploadForm()
var = UploadFormVar()
files=Upload.objects.all()
return render(request,'home.html',{'form': img, 'form_b': var})