How to write multiple view function for single page - django

I'm trying to perform multiple operation for single web page. I'm struggling to write multiple function view for single web page. How to do that. Help me in that.
def home_view(request):
if 'username' in request.session:
if request.method == 'GET':
form = ProfileForm(request.GET)
if form.is_valid:
profile_info = Profile.objects.filter(username=username).values()
for i in profile_info:
profiledict = i
return render(request, 'home/index.html', {'profile_first_name': profiledict['first_name'],
'profile_last_name': profiledict["last_name"],
'profile_phone_number': profiledict['phone_number'],
'profile_email': profiledict['email'],
'profile_address': profiledict['address'],
'profile_image': profiledict['image']})
elif request.method == 'POST':
first_name = request.POST.get('first_name')
last_name = request.POST.get('last_name')
phone_number = request.POST.get('phone_number')
email = request.POST.get('email')
address = request.POST.get('address')
image = request.FILES['images']
file_storage = FileSystemStorage()
obj = Profile.objects.all().filter(username=username)
if len(obj) > 0:
obj.update(first_name=first_name, last_name=last_name, phone_number=phone_number,
email=email, address=address, image=file_storage.save(image.name, image))
return redirect('/home/')
return redirect('/home/')
else:
return redirect('/login/')
def home2_view(request):
if 'username' in request.session:
business_objs = AddBusiness.objects.all().values()
return render(request, 'home/index.html', {'business_objs': business_objs})
else:
return redirect('/login/')
I tried like this, it performing only first operation. Here i'm trying to perform 3 operation, GET(extract data from database and displaying in HTML form), POST(updating the form data), and Displaying all database rows and columns in HTML page.

Related

Upload in Django

I was trying to understand how to upload files using Django, so I used the example (latest version, upload is working):
https://github.com/axelpale/minimal-django-file-upload-example
I have a few Questions now:
How do I set a max file size? (I have checked the documentation of Django, but I don't get it)
Is there a way for me to read the file before the user uploads it?
(i.e a program that checks certain things and if they are ok, it can be uploaded)
Here is some code...
model.py:
class Document(models.Model):
name= models.CharField(max_length=500)
docfile= models.FileField(upload_to='documents/%Y/%m/%d', verbose_name="", validators=[validate_file_size])
def __str__(self):
return self.name + ": " + str(self.docfile)
validators.py:
def validate_file_size(value):
filesize= value.size
if filesize > 20971520:
raise ValidationError("File too big")
else:
return value
views.py:
def uploadView(request):
message = 'Upload your .csv-File'
if request.method == 'POST':
form = documentForm(request.POST, request.FILES)
if form.is_valid():
newDoc = Document(docfile=request.FILES['docfile'])
newDoc.save()
return redirect(uploadView)
else:
message = 'The form is not valid.'
else:
form = documentForm()
documents = Document.objects.all()
context = {'documents': documents, 'form': form, 'message': message}
return render(request, 'upload.html', context)

"RESOLVED" two forms one submit button error | IndentationError: expected an indented block

[RESOLVED] I FOUND THE SOLUTION AND UPDATED WITH THE WORKING CODE BELOW
I'm trying to submit two forms with one button.
I check a few other posts in here, but I'm not sure if the code below is the correct.
def cars_detail(request, car_id):
car = Car.objects.get(id=car_id)
profile_form = ProfileForm()
booking_form = BookingForm()
return render(request, 'cars/detail.html', { 'car': car, 'booking_form': booking_form, 'profile_form': profile_form })
def addbooking(request, car_id):
if request.method == 'POST':
profile_form = ProfileForm(request.POST)
booking_form = BookingForm(request.POST)
print(request.POST)
if profile_form.is_valid() or booking_form.is_valid():
# do stuff here
# form = ProfileForm(request.POST)
new_profile = profile_form.save(commit=False)
new_profile.car_id = car_id
new_profile.user_id = request.user.id
new_profile.save()
# do stuff here
# form = BookingForm(request.POST)
new_booking = booking_form.save(commit=False)
new_booking.car_id = car_id
new_booking.user_id = request.user.id
new_booking.save()
return redirect('detail', car_id=car_id)
else:
profile_form = ProfileForm(prefix="profile_form")
booking_form = BookingForm(prefix="booking_form")
You have no code in the block after the “if”.
If there’s nothing to do in that instance negate the condition and remove the “else”
But do you want to reset both forms if only one of them is invalid? You might want this instead
if !profile_form.is_valid():
profile_form = Profile_form(prefix="profile_form")
if !booking_form.is_valid():
booking_form = Booking_form(prefix="booking_form")

Uniqueness validation in django form (Both ADD and EDIT)

Here, I wanted to achieve mobile number uniqueness validation in both conditions i.e. at the time of ADD and EDIT form details.
I am facing a problem in form edit mode because I am unable to perform uniqueness validation in form edit submit.
I wanted only a single mobile no to be stored in a database. While I am editing the form it is bypassing my logic and allowing duplicate entries from EDIT.
Could you guys suggest any solution for uniqueness validation?
forms.py
class StudentForm(forms.Form):
name = forms.CharField(required=True,max_length=10)
city = forms.CharField(required=True,max_length=10)
mobile_no = forms.CharField(required=True, max_length=10)
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request', None)
super(StudentForm, self).__init__(*args, **kwargs)
def clean_mobile_no(self):
mobile_no = self.cleaned_data.get('mobile_no')
id = self.request.POST.get('id')
if stu_id:
if Student.objects.filter(mobile_no=mobile_no).count()>1:
raise forms.ValidationError("You have already added mobile no.")
else:
return mobile_no
elif mobile_no and Student.objects.filter(mobile_no=mobile_no).exists():
raise forms.ValidationError("Alreadsy exists.")
return mobile_no
views.py
def add_edit_(request, stu_id=None):
if stu_id:
stu = Student.objects.get(pk=stu_id)
if request.method == 'POST':
form = StudentForm(request.POST, request=request)
if form.is_valid():
name = request.POST['name ']
city = request.POST['ccity']
mobile_no = form.cleaned_data['mobile_no']
if stu_id:
stu.name=name
stu.ccity=city
stu.mobile_no=mobile_no
cstu.save()
messages.success(request, 'Edit Successfully...')
return redirect('/.../')
else:
p = Student(name=name, city=city, mobile_no=smobile_no
)
p.save()
messages.success(request, 'Information added Successfully...')
return redirect('/../')
elif id:
form = CStudentForm(initial={'name':stu.name,
'city':stu.city,'mobile_no':std.mobile_no '})
else:
form = StudentForm()
context = {
'form': form,
'stu_id':stu_id,
}
return render(request, 'student.html', context=context)
Thank you in advance.

Processing a Django form when there are multiple possibilities?

What is the correct way to process a Django form within a view if you don't know which form to expect when entering the view? I have a view which determines the type of form to render based on a session variable:
# views.py
def enter_location(request):
country = request.session['country']
if request.method == "POST":
if country == 'US':
form = USLocationForm(request.POST)
elif country == 'GB':
form = GBLocationForm(request.POST)
elif country == 'CA':
form = CALocationForm(request.POST)
else:
form = OtherLocationForm(request.POST)
if form.is_valid():
# do stuff...
pass
else:
if country == 'US':
form = USLocationForm(initial={'country': country})
elif country == 'GB':
form = GBLocationForm(initial={'country': country})
elif country == 'CA':
form = CALocationForm(initial={'country': country})
else:
form = OtherLocationForm(initial={'country': country})
context = {'form': form}
return render(request, template, context)
Clearly this is ugly code and it doesn't scale as I add more countries. I tried to keep my view short by determining the form type via a helper function:
# views.py
from location.forms import LocationForm
def enter_location(request):
country = request.session['country']
if request.method == "POST":
form = LocationForm.get_form(country)
submitted_form = form(request.POST)
if submitted_form.is_valid():
# do stuff...
pass
else:
form = LocationForm.get_form(country)
context = {'form': form}
return render(request, template, context)
# location/forms.py
class LocationForm(forms.Form):
country = forms.ChoiceField(choices = choices.COUNTRIES_AND_EMPTY,)
city = forms.CharField()
email = forms.EmailField()
#staticmethod
def get_form(country):
if country == 'US':
return form = USLocationForm(initial={'country': country})
elif country == 'GB':
return form = GBLocationForm(initial={'country': country})
elif country == 'CA':
return form = CALocationForm(initial={'country': country})
else:
return form = OtherLocationForm(initial={'country': country})
The problem is that when the view runs, I get "TypeError "'USLocationForm' object is not callable"" at the line:
submitted_form = form(request.POST)
This also happens when country is 'GB' or 'CA' and the appropriate form has been chosen. I ran the debugger and did "type(form)" using both views and the form attributes appear to be the same in either case. Is there something different happening when you first instantiate the form in the GET block versus instantiating it again during the POST and then populating it with the posted data? What's the Django way of handling this situation when one of many possible forms can be chosen?
Thanks.
There is no "right way" to handle this, but one thing you could do to consolidate is use a mapping.
Example:
form_mappings = {
'US': USLocationForm,
'GB': GBLocationForm,
#...
}
def enter_location(request):
country = request.session['country']
country_form = form_mappings.get(country, OtherLocationForm)
if request.method == "POST":
form = country_form(request.POST)
#...
else:
form = country_form(initial={'country': country})
This way, you can extend the code for further countries, and not have to change the code at all..

Django pre-populated form that updates record on submit

model:
class locations(models.Model):#table
Name = models.CharField(max_length=50,default='Joes quick stop', unique=True)
shop_code = models.CharField(max_length=5,default='AB005',unique=True)
manager = models.ManyToManyField(users)
ast_manager = models.ManyToManyField(users, blank=True, related_name='ast_mng')
sales_manager = models.ManyToManyField(users, blank=True, related_name='sales_mng')
forms:
class locations(models.Model):
Name = models.CharField(max_length=50,default='Joes quick stop', unique=True)
shop_code = models.CharField(max_length=5,default='AB005',unique=True)
manager = models.ManyToManyField(users)
ast_manager = models.ManyToManyField(users, blank=True, related_name='ast_mng')
sales_manager = models.ManyToManyField(users, blank=True, related_name='sales_mng')
class locationsForm(ModelForm):
class Meta:
model = locations
Views
def locations(request):
locations = locations.objects.values().filter(id=request.session['location'])
data=locations[0]
if request.method == 'GET':
if request.session['Manager']== True:
form = locationsForm(initial=data)
context = {'locations': locations, 'form': form}
return render(request, 'locations/locations.html', context)
elif request.method == 'POST':
form=locationsForm(request.POST, instance=data)
if form.is_valid():
cd=form.cleaned_data
form.save()
form = locationsForm()
locations= locations.objects.values().filter(id=request.session['depot'])
context = {'locations': locations}
return render(request, 'locations/locations.html', context)
else:
context = {'locations': locations, 'form': form}
return render(request, 'locations/locations.html', context)
I am trying to display a form that is populated with the relevant data but the user can change and then save/update the form. The above code does a good job of displaying the form with the relevant data but when the user tries to submit it the system tries to save a new record instead of updating the old and fails. I never get past if form.is_valid():
Your problem is that you are converting your locations objects into a list of dictionaries. And then passing a dictionary into the form as instance.
This is happening because you are calling the .values() method on the queryset. That method returns a special ValuesQuerySet which basically looks like a list of dictionaries. Not a list of locations objects.
The instance parameter on the form needs to be an object, not a dictionary. So just simply remove the .values() calls, and it should work. Like this:
def locations(request):
locations = locations.objects.filter(id=request.session['location'])
first_location=locations[0]
if request.method == 'GET':
if request.session['Manager']== True:
form = locationsForm(instance=first_location)
context = {'locations': locations, 'form': form}
return render(request, 'locations/locations.html', context)
elif request.method == 'POST':
form=locationsForm(request.POST, instance=first_location)
if form.is_valid():
cd=form.cleaned_data
form.save()
form = locationsForm()
locations= locations.objects.values().filter(id=request.session['depot'])
context = {'locations': locations}
return render(request, 'locations/locations.html', context)
else:
context = {'locations': locations, 'form': form}
return render(request, 'locations/locations.html', context)