Confusion in form.save() in two different models - html

I am having problems in displaying the page due to models. I honestly don't know what the problem is and every solution I see here is beyond me, since I am only beginning to learn Django. Here's the summary:
I have created two forms from two models(which are interrelated) and rendering the data from those forms in a single page. The data displays fine on the dashboard panel and the submission does save it to the database. I have tried overriding the save function in form but with no result. However, whenever I try and load the pages containing same data (display pages like home for customers)I am hit with:
Traceback (most recent call last):
File "C:\Users\shahi\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "C:\Users\shahi\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\shahi\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "D:\Softwarica\3rd semester\Modern Web\Assignment\Project - Farmer's Market\farmersmarket\home\views.py", line 9, in index
order, created = Order.objects.get_or_create(customer=customer, complete=False)
File "C:\Users\shahi\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\db\models\manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "C:\Users\shahi\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\db\models\query.py", line 559, in get_or_create
return self.get(**kwargs), False
File "C:\Users\shahi\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\db\models\query.py", line 419, in get
raise self.model.MultipleObjectsReturned(
shop.models.Order.MultipleObjectsReturned: get() returned more than one Order -- it returned 2!
The code in forms.py:
from django.forms import ModelForm
from shop.models import *
class OrderForm(ModelForm):
class Meta:
model = Order
fields = ('customer',)
class OrderItemForm(ModelForm):
class Meta:
model = OrderItem
fields = ('item', 'status',)
views.py
def createOrder(request):
form_order = OrderForm()
form_orderitem = OrderItemForm()
if request.method == 'POST':
# print('Printing POST', request.POST)
form_order = OrderForm(request.POST)
form_orderitem = OrderItemForm(request.POST)
if form_order.is_valid() and form_orderitem.is_valid():
form_order.save()
form_orderitem.save()
return redirect('/dashboard')
context = {'form_order': form_order, 'form_orderitem': form_orderitem}
return render(request, 'dashboard/order_form.html', context)
I have tried overriding the save function in form but with no result.

get() cannot be used for when more than 1 objects are returned. try with filter().
Do check first() or last(), if it helps you.

Related

Django exists query not work in if and else clause?

In given below if Medicine table consists medicine_name then query execute fine, but when medicine name doesn't exist on the Corresponding table then error is occured.
Matching Query Doesn't Exists
views.py Code
#api_view(['POST'])
def addPeople(request):
m = People()
m.bp_no = request.POST['bp_no']
m.name = request.POST['name']
m.corporation_name = request.POST['corporation_name']
m.medicine_name = request.POST['medicine_name']
m.no_of_medicine = request.POST['no_of_medicine']
existing = Medicine.objects.get(medicine_name=m.medicine_name).no_of_medicine - int(m.no_of_medicine)
p_key = Medicine.objects.get(medicine_name=m.medicine_name).id
if Medicine.objects.filter(medicine_name=m.medicine_name).exists():
if existing > 0:
m.save()
Medicine.objects.filter(id=p_key).update(no_of_medicine=existing)
return Response({"message": "Successfully Recorded"})
else:
return Response({"message": "Not much Medicine Stored"})
else:
return Response({"message": "Medicine is not Stored"})
models.py
class People(models.Model):
bp_no = models.IntegerField(blank=False,null=False)
name = models.CharField(blank=False,null=False,max_length=200)
corporation_name = models.CharField(blank=False,null=False,max_length=200)
medicine_name = models.CharField(blank=False,null=False,max_length=200)
no_of_medicine = models.IntegerField()
class Medicine(models.Model):
medicine_name = models.CharField(null=False,blank=False,max_length=200)
no_of_medicine = models.IntegerField(null=False,blank=False)
def __str__(self):
return self.medicine_name
Error Traceback: When Medicine table doesn't contains the corresponding filter name then This error will be shown
Internal Server Error: /api/add-people/
Traceback (most recent call last):
File "C:\Users\MonirHossain\AppData\Roaming\Python\Python39\site-packages\django\core\handlers\exception.py", line 47, in inner
response = get_response(request)
File "C:\Users\MonirHossain\AppData\Roaming\Python\Python39\site-packages\django\core\handlers\base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\MonirHossain\AppData\Roaming\Python\Python39\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "C:\Users\MonirHossain\AppData\Roaming\Python\Python39\site-packages\django\views\generic\base.py", line 70, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\MonirHossain\AppData\Roaming\Python\Python39\site-packages\rest_framework\views.py", line 509, in dispatch
response = self.handle_exception(exc)
File "C:\Users\MonirHossain\AppData\Roaming\Python\Python39\site-packages\rest_framework\views.py", line 469, in handle_exception
self.raise_uncaught_exception(exc)
File "C:\Users\MonirHossain\AppData\Roaming\Python\Python39\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
raise exc
File "C:\Users\MonirHossain\AppData\Roaming\Python\Python39\site-packages\rest_framework\views.py", line 506, in dispatch
response = handler(request, *args, **kwargs)
File "C:\Users\MonirHossain\AppData\Roaming\Python\Python39\site-packages\rest_framework\decorators.py", line 50, in handler
return func(*args, **kwargs)
File "E:\django\backend\medirecords\api\views.py", line 37, in addPeople
existing = Medicine.objects.get(medicine_name=m.medicine_name).no_of_medicine - int(m.no_of_medicine)
File "C:\Users\MonirHossain\AppData\Roaming\Python\Python39\site-packages\django\db\models\manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "C:\Users\MonirHossain\AppData\Roaming\Python\Python39\site-packages\django\db\models\query.py", line 435, in get
raise self.model.DoesNotExist(
api.models.Medicine.DoesNotExist: Medicine matching query does not exist.
I haven't tested this, but purely in terms of handling objects not found, I have a suggestion you can try to simplify the conditions / flow.
.get(): Wrap in try / except
get(*args, **kwargs) raises Model.DoesNotExist when not found.
When there's a not found, you need to determine how you want to handle it. For example, you can have a default fallback value, or raise an error.
In this case the code would fail if the existing medicine wasn't found, so I will have it raise.
#api_view(["POST"])
def addPeople(request):
medicine_name = request.POST["medicine_name"]
try:
medicine = Medicine.objects.get(medicine_name=medicine_name)
except Medicine.DoesNotExist:
return Response({"message": "Not much Medicine Stored"})
m = People()
m.bp_no = request.POST["bp_no"]
m.name = request.POST["name"]
m.corporation_name = request.POST["corporation_name"]
m.medicine_name = medicine_name
m.no_of_medicine = request.POST["no_of_medicine"]
existing = medicine.no_of_medicine - int(m.no_of_medicine)
p_key = medicine.id
if medicine.exists():
if existing > 0:
m.save()
medicine.num_of_medicine = existing
medicine.save(update_fields=["num_of_medicine"])
return Response({"message": "Successfully Recorded"})
else:
return Response({"message": "Not much Medicine Stored"})
else:
return Response({"message": "Medicine is not Stored"})
Move object check earlier
Since the request relies on Medicine, this is should be caught early as possible.
Uses try/catch as .get() will always raise when object is not found
The alternative is to do .exists() or filter(*args, **kwargs) + .first()
Update dependent model via Model.save() and limit field updated to num_of_medicine via update_fields.
get_object_or_404()
get_object_or_404(klass, *args, **kwargs) can also be used in lieu of the earlier try/catch block:
from django.shortcuts import get_object_or_404
medicine = get_object_or_404(Medicine.objects.all(), medicine_name=m.medicine_name)
existing = medicine.no_of_medicine - int(m.no_of_medicine)
Final note
I'm assuming this is an example, but it also may be good to validate request.POST["no_of_medicine"] in the POST data against a backend source of truth to make sure it's not faked.

How to return single object as a json response inside django function?

I just want to get a single object of User model as a json response. I couldn't figure out how can i do that..
right now i'm getting an error that 'User' object is not iterable
Here is my function:
def some_view(username_to_toggle):
print(username_to_toggle,"User to togle")
user = User.objects.get(username__iexact=username_to_toggle)
print(user,"User object")
user_json = serializers.serialize('json', user,many=False)
print(user,"User json")
return HttpResponse(user_json, content_type='application/json')
TraceBack :
Traceback (most recent call last):
File "/home/hamza/Mydjangoproject/grabpublic/grabpublic/Grab_env/lib/python3.6/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/home/hamza/Mydjangoproject/grabpublic/grabpublic/Grab_env/lib/python3.6/site-packages/django/core/handlers/base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/home/hamza/Mydjangoproject/grabpublic/grabpublic/Grab_env/lib/python3.6/site-packages/django/core/handlers/base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/hamza/Mydjangoproject/grabpublic/grabpublic/Grab_env/lib/python3.6/site-packages/django/views/generic/base.py", line 71, in view
return self.dispatch(request, *args, **kwargs)
File "/home/hamza/Mydjangoproject/grabpublic/grabpublic/Grab_env/lib/python3.6/site-packages/django/contrib/auth/mixins.py", line 52, in dispatch
return super().dispatch(request, *args, **kwargs)
File "/home/hamza/Mydjangoproject/grabpublic/grabpublic/Grab_env/lib/python3.6/site-packages/django/views/generic/base.py", line 97, in dispatch
return handler(request, *args, **kwargs)
File "/home/hamza/Mydjangoproject/grabpublic/grabpublic/profiles/views.py", line 65, in post
profile_, is_following,json_follower = UserProfile.objects.toggle_follow(request.user, request.user.id ,username_to_toggle,json_follower)
File "/home/hamza/Mydjangoproject/grabpublic/grabpublic/profiles/models.py", line 72, in toggle_follow
json_follower = some_view(username_to_toggle)
File "/home/hamza/Mydjangoproject/grabpublic/grabpublic/profiles/models.py", line 45, in some_view
user_json = serializers.serialize('json', user,many=False)
File "/home/hamza/Mydjangoproject/grabpublic/grabpublic/Grab_env/lib/python3.6/site-packages/django/core/serializers/__init__.py", line 128, in serialize
s.serialize(queryset, **options)
File "/home/hamza/Mydjangoproject/grabpublic/grabpublic/Grab_env/lib/python3.6/site-packages/django/core/serializers/base.py", line 90, in serialize
for count, obj in enumerate(queryset, start=1):
TypeError: 'User' object is not iterable
The serialize method from django.core.serializers doesn't have many option and it always needs a list or a queryset of model objects for the serialization. If you always want to serialize only one object, try using either of those:
first method, using queryset:
def some_view(username_to_toggle):
print(username_to_toggle,"User to togle")
users = User.objects.filter(username__iexact=username_to_toggle)
print(users,"User objects")
user_json = serializers.serialize('json', users)
print(user,"User json")
return HttpResponse(user_json, content_type='application/json')
or a second method, using list:
def some_view(username_to_toggle):
print(username_to_toggle,"User to togle")
user = User.objects.get(username__iexact=username_to_toggle)
print(user,"User object")
user_json = serializers.serialize('json', [user])
print(user,"User json")
return HttpResponse(user_json, content_type='application/json')
many=False or many=True is a feature of Django REST Framework serializators, but their usage is different and more complex as you need to declare a separate serializer for every Model you want to serialize.

TypeError Object id is not JSON serializable

I have a Django view that is raising an error when the template tries to render:
TypeError: is not JSON serializable
(Where 76 is the id field)
Here is the view
def view2(request, model1object_id):
model1object = Model1.objects.get(pk=model1object_id)
# HERE
session_object = request.session.get('content')
if session_object:
del request.session['content']
request.session['content'] = model1object
context = {
"model1object": model1object,
....
}
return render(request, 'app/template2.html', context)
Here's my model for Model1:
class Model1(models.Model):
date_field = models.DateField()
another_field = models.CharField(max_length= 50, default="...")
def __str__(self):
return unicode(self.id) or u''
def get_absolute_url(self):
return reverse('app:model1', kwargs={'id': self.id})
EDIT: Traceback ->
Traceback (most recent call last):
File "/Library/Python/2.7/site-packages/django/core/handlers/base.py", line 235, in get_response
response = middleware_method(request, response)
File "/Library/Python/2.7/site-packages/django/contrib/sessions/middleware.py", line 50, in process_response
request.session.save()
File "/Library/Python/2.7/site-packages/django/contrib/sessions/backends/db.py", line 82, in save
obj = self.create_model_instance(data)
File "/Library/Python/2.7/site-packages/django/contrib/sessions/backends/db.py", line 68, in create_model_instance
session_data=self.encode(data),
File "/Library/Python/2.7/site-packages/django/contrib/sessions/backends/base.py", line 91, in encode
serialized = self.serializer().dumps(session_dict)
File "/Library/Python/2.7/site-packages/django/core/signing.py", line 95, in dumps
return json.dumps(obj, separators=(',', ':')).encode('latin-1')
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 250, in dumps
sort_keys=sort_keys, **kw).encode(obj)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 207, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 270, in iterencode
return _iterencode(o, 0)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 184, in default
raise TypeError(repr(o) + " is not JSON serializable")
TypeError: <Model1: 76> is not JSON serializable
thanks
The error is because you are trying to save a model instance in the session, and the session middleware cannot serialize it to JSON.
request.session['content'] = model1object
It may be enough to store the id of the object instead of the object itself.
request.session['content_id'] = model1object.id
...
# retrieve from db later
model1object = Model1.objects.get(id=request.session['content_id'])
If you need to store more information in the session than the id, then you'll have to convert it to a format that is JSON serializable. For a simple model, it might be easiest to create a Python dict.
request.session['content'] = {
'id': model1object.id,
'name': model1object.name,
...
}
For more complicated models, you could look at the docs on serializing Django objects.

Handling Django form.save() ValueError

I am a newbie to Django error handling and I spent a week trying to figure out what exactly goes wrong when trying to update a MySQL table using Django forms. I end up with ValueError: invalid literal for int() with base 10: '\x01' error. I tried to surround the erroneous code with try catch block trapping valueError and printing the row sql query, and here's what I get.
The code:
def updateTask(request, task_id):
#cur_usr_sale_point = PersonUnique.objects.filter(employees__employeeuser__auth_user = request.user.id).values_list('agreementemployees__agreement_unique__sale_point_id',flat=True)
selected_task = Tasks.objects.get(id=task_id)
responsible_people = TaskResponsiblePeople.objects.get(task_id = task_id)
task_table = Tasks. objects.all()
if request.method == 'POST':
task_form = TaskForm(request.POST,instance=selected_task)
responsible_people_form = TaskResponsiblePeopleForm(request.POST, instance = responsible_people)
if task_form.is_valid() and responsible_people_form.is_valid():
responsible_people_instance = responsible_people_form.save(commit=False)
try:
responsible_people_instance.task = task_form.save()
responsible_people_form.save()
except ValueError:
from django.db import connection
print connection.queries[-1]
return HttpResponseRedirect(reverse('task_list'))
Print gives me an absolutely valid MySQL Select-statement (to my surpise, I expected an update-statement).
The traceback without try-catch block:
Internal Server Error: /task_list/update_task/200/
Traceback (most recent call last):
File "C:\Python27\lib\site-packages\django\core\handlers\base.py", line 149, in get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Python27\lib\site-packages\django\core\handlers\base.py", line 147, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "\\10.8.0.1\share\djprj\djprj\djprj\task\views.py", line 101, in updateTask
task_form.save();
File "C:\Python27\lib\site-packages\django\forms\models.py", line 451, in save
self.instance.save()
File "C:\Python27\lib\site-packages\django\db\models\base.py", line 700, in save
force_update=force_update, update_fields=update_fields)
File "C:\Python27\lib\site-packages\django\db\models\base.py", line 728, in save_base
updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
File "C:\Python27\lib\site-packages\django\db\models\base.py", line 793, in _save_table
forced_update)
File "C:\Python27\lib\site-packages\django\db\models\base.py", line 843, in _do_update
return filtered._update(values) > 0
File "C:\Python27\lib\site-packages\django\db\models\query.py", line 645, in _update
return query.get_compiler(self.db).execute_sql(CURSOR)
File "C:\Python27\lib\site-packages\django\db\models\sql\compiler.py", line 1149, in execute_sql
cursor = super(SQLUpdateCompiler, self).execute_sql(result_type)
File "C:\Python27\lib\site-packages\django\db\models\sql\compiler.py", line 837, in execute_sql
sql, params = self.as_sql()
File "C:\Python27\lib\site-packages\django\db\models\sql\compiler.py", line 1117, in as_sql
val = field.get_db_prep_save(val, connection=self.connection)
File "C:\Python27\lib\site-packages\django\db\models\fields\__init__.py", line 728, in get_db_prep_save
prepared=False)
File "C:\Python27\lib\site-packages\django\db\models\fields\__init__.py", line 720, in get_db_prep_value
value = self.get_prep_value(value)
File "C:\Python27\lib\site-packages\django\db\models\fields\__init__.py", line 1853, in get_prep_value
return int(value)
ValueError: invalid literal for int() with base 10: '\x01'
[10/Apr/2016 11:15:46] "POST /task_list/update_task/200/ HTTP/1.1" 500 126245
Help me out please !!!
EDIT: added is_valid method
You need to first use the form's is_valid method:
A Form instance has an is_valid() method, which runs validation routines for all its fields. When this method is called, if all fields contain valid data.
from django.shortcuts import render
from django.http import HttpResponseRedirect
from .forms import NameForm
def get_name(request):
# 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 = NameForm(request.POST)
# check whether it's valid:
if form.is_valid():
# process the data in form.cleaned_data as required
# ...
# redirect to a new URL:
return HttpResponseRedirect('/thanks/')
# if a GET (or any other method) we'll create a blank form
else:
form = NameForm()
return render(request, 'name.html', {'form': form})
Source: Django Docs: Working with forms
I would recommend that you read the above documentation.

How to pass urls from CSV list into a python GET request

I have a CSV file, which contains a list of Google extension IDs.
I'm writing a code that will read the extension IDs, add the webstore url, then perform a basic get request:
import csv
import requests
with open('small.csv', 'rb') as f:
reader = csv.reader(f)
for row in reader:
urls = "https://chrome.google.com/webstore/detail/" + row[0]
print urls
r = requests.get([urls])
Running this code results in the following Traceback:
Traceback (most recent call last):
File "C:\Users\tom\Dropbox\Python\panya\test.py", line 9, in <module>
r = requests.get([urls])
File "C:\Python27\lib\site-packages\requests\api.py", line 69, in get
return request('get', url, params=params, **kwargs)
File "C:\Python27\lib\site-packages\requests\api.py", line 50, in request
response = session.request(method=method, url=url, **kwargs)
File "C:\Python27\lib\site-packages\requests\sessions.py", line 465, in request
resp = self.send(prep, **send_kwargs)
File "C:\Python27\lib\site-packages\requests\sessions.py", line 567, in send
adapter = self.get_adapter(url=request.url)
File "C:\Python27\lib\site-packages\requests\sessions.py", line 641, in get_adapter
raise InvalidSchema("No connection adapters were found for '%s'" % url)
InvalidSchema: No connection adapters were found for '['https://chrome.google.com/webstore/detail/blpcfgokakmgnkcojhhkbfbldkacnbeo']'
How can revise the code, so that it would accept the urls in the list, and make the GET request?
requests.get expects a string, but you're creating and passing a list [urls]
r = requests.get([urls])
Change it to just
r = requests.get(urls)
and it should work.