How do you know exactly what causes the form not to be valid while processing form with model - django-models

Hey Mentors and Teachers, we appreciate having you, please help a young one here in this industry having not much experience this is one of my common challenges since I am still trying new ways, here I am using a model to save a form and also model form without having to use the form in the template. I am sure using the model form directly would have solved it quickly but I want the ability to be able to style my form, especially each individual field,
the version being used in this is django 3.1
Help me know how to make this code work
class Order(models.Model):
STATUS = (
('New', 'New'),
('Accepted', 'Accepted'),
('Completed', 'Completed'),
('Cancelled', 'Cancelled'),
)
user = models.ForeignKey(Account, on_delete=models.SET_NULL, null=True)
payment = models.ForeignKey(Payment, on_delete=models.SET_NULL, blank=True, null=True)
order_number = models.CharField(max_length=20)
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
phone = models.CharField(max_length=15)
email = models.EmailField(max_length=50)
address_line_1 = models.CharField(max_length=50)
address_line_2 = models.CharField(max_length=50, blank=True)
country = models.CharField(max_length=50)
state = models.CharField(max_length=50)
city = models.CharField(max_length=50)
order_note = models.CharField(max_length=100, blank=True)
order_total = models.FloatField()
tax = models.FloatField()
status = models.CharField(max_length=10, choices=STATUS, default='New')
ip = models.CharField(blank=True, max_length=20)
is_ordered = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def full_name(self):
return f'{self.first_name}'
and here is a view that is am using:
def place_order(request, total=0, quantity=0,):
current_user = request.user
# If the cart count is less than or equal to 0, then redirect back to shop
cart_items = CartItem.objects.filter(user=current_user)
cart_count = cart_items.count()
if cart_count <= 0:
return redirect('store')
grand_total = 0
tax = 0
for cart_item in cart_items:
total += (cart_item.product.price * cart_item.quantity)
quantity += cart_item.quantity
tax = (2 * total)/100
grand_total = total + tax
if request.method == 'POST':
form = OrderForm(request.POST)
if form.is_valid():
# Store all the billing information inside Order table
data = Order()
data.user = current_user
data.first_name = form.cleaned_data['first_name']
data.last_name = form.cleaned_data['last_name']
data.phone = form.cleaned_data['phone']
data.email = form.cleaned_data['email']
data.address_line_1 = form.cleaned_data['address_line_1']
data.address_line_2 = form.cleaned_data['address_line_2']
data.country = form.cleaned_data['country']
data.state = form.cleaned_data['state']
data.city = form.cleaned_data['city']
data.more_address_details = form.cleaned_data['more_address_details']
data.order_note = form.cleaned_data['order_note']
data.order_note = form.cleaned_data['order_note']
data.order_total = grand_total
data.tax = tax
data.ip = request.META.get('REMOTE_ADDR')
data.save()
# Generate order number
yr = int(datetime.date.today().strftime('%Y'))
dt = int(datetime.date.today().strftime('%d'))
mt = int(datetime.date.today().strftime('%m'))
d = datetime.date(yr,mt,dt)
current_date = d.strftime("%Y%m%d") #20210305
order_number = current_date + str(data.id)
data.order_number = order_number
data.save()
order = Order.objects.get(user = current_user, is_ordered = False, order_number = order_number)
context = {
'order': order,
'cart_items': cart_items,
'total': total,
'tax': tax,
'grand_total': grand_total,
}
return render(request, 'orders/payments.html', {'context': context})
else:
return redirect('checkout')
else:
return redirect('store')
and here is what is in the template:
def place_order(request, total=0, quantity=0,):
current_user = request.user
# If the cart count is less than or equal to 0, then redirect back to shop
cart_items = CartItem.objects.filter(user=current_user)
cart_count = cart_items.count()
if cart_count <= 0:
return redirect('store')
grand_total = 0
tax = 0
for cart_item in cart_items:
total += (cart_item.product.price * cart_item.quantity)
quantity += cart_item.quantity
tax = (2 * total)/100
grand_total = total + tax
if request.method == 'POST':
form = OrderForm(request.POST)
if form.is_valid():
# Store all the billing information inside Order table
data = Order()
data.user = current_user
data.first_name = form.cleaned_data['first_name']
data.last_name = form.cleaned_data['last_name']
data.phone = form.cleaned_data['phone']
data.email = form.cleaned_data['email']
data.address_line_1 = form.cleaned_data['address_line_1']
data.address_line_2 = form.cleaned_data['address_line_2']
data.country = form.cleaned_data['country']
data.state = form.cleaned_data['state']
data.city = form.cleaned_data['city']
data.more_address_details = form.cleaned_data['more_address_details']
data.order_note = form.cleaned_data['order_note']
data.order_note = form.cleaned_data['order_note']
data.order_total = grand_total
data.tax = tax
data.ip = request.META.get('REMOTE_ADDR')
data.save()
# Generate order number
yr = int(datetime.date.today().strftime('%Y'))
dt = int(datetime.date.today().strftime('%d'))
mt = int(datetime.date.today().strftime('%m'))
d = datetime.date(yr,mt,dt)
current_date = d.strftime("%Y%m%d") #20210305
order_number = current_date + str(data.id)
data.order_number = order_number
data.save()
order = Order.objects.get(user = current_user, is_ordered = False, order_number = order_number)
context = {
'order': order,
'cart_items': cart_items,
'total': total,
'tax': tax,
'grand_total': grand_total,
}
return render(request, 'orders/payments.html', {'context': context})
else:
return redirect('checkout')
else:
return redirect('store')
I AM ALWAYS BLOWNED BY THE KIND OF PEOPLE WHO ALWAYS HELP WITHOUT EXPECTING ANYTHING IN RETURN, REALLY THANKS

Just found where the error was, had forgotten to add the name of a form field "more_address_details" in the template

Related

Django - Saving contents of a form into a database

class InitialForm(forms.Form):
Teacher_Name = forms.CharField(label='Teacher Name')
Subject = forms.CharField(label = 'Subject')
Question = forms.CharField(label = 'What is the first question?')
Topic = forms.CharField(label = 'What topic is this on?')
Option1_Q = forms.CharField(label = 'What is the first option?')
Option2_Q = forms.CharField(label = 'What is the second option?')
Option3_Q = forms.CharField(label = 'What is the third option?')
Option4_Q = forms.CharField(label = 'What is the fourth option?')
Answer_Q = forms.CharField(label = 'Which option is the correct option?', widget=forms.Select(choices=Options))
class Questions(models.Model):
testID = AutoSlugField(unique=True)
teacherID = models.ForeignKey(Teacher, on_delete=models.CASCADE)
studentID = models.ForeignKey(Student, on_delete=models.CASCADE)
Subject = models.CharField(max_length=1000)
Q = models.CharField(max_length=1000)
Topic = models.CharField(max_length=1000)
Option1_Q = models.CharField(max_length=1000)
Option2_Q = models.CharField(max_length=1000)
Option3_Q = models.CharField(max_length=1000)
Option4_Q = models.CharField(max_length=1000)
AnswerQ = models.CharField(max_length=1000)
def teachertests(request):
form = InitialForm()
if request.method == "POST":
form = InitialForm(request.POST)
form.save()
return render(request, 'teachertests.html', {'form':form})
Hey, pretty new to coding in general and wanted to save the contents of the form into the database and then display specific fields from the form, not sure what I had done wrong, could anyone help?
When you use a form it is important to add the form.is_valid() since from what you see you did not indicate in your form if there are fields that are not mandatory with the require=False as long as it is not valid it will not be saved
def teachertests(request):
form = InitialForm()
if request.method == "POST":
form = InitialForm(request.POST)
if form.is_valid():
data_form = form.cleaned_data
question = Question()
question.Option1_Q = data_form.get('Option1_Q')
# ....... all fields form
question.save()
return render(request, 'teachertests.html', {'form':form})

How to create data to the database using views

I am trying to create order amount from the catalogue which works like a shopping cart but the amount returned is 1 for all orders made:
views.py
def get_user_pending_order(request):
#get order from correct profile
user_profile = get_object_or_404(Profile,user=request.user)
order = Order.objects.filter(owner=user_profile,is_ordered=True)
if order.exists():
#to get an order in the list of filtered orders
return order[0]
return 0
def add_to_catalogue(request,employee_id):#product_id,employee_id
user_profile= get_object_or_404(Profile, user =request.user)
order_to_purchase = get_user_pending_order(request)
amount= self.order_to_purchase.get_catalogue_total(),
employee = Employee.objects.get(pk=employee_id)
if employee in request.user.profile.ebooks.all():
messages.info(request,'you already own this ebook')
return redirect(reverse('freelance:employee_list'))
order_task,status =
OrderTask.objects.get_or_create(employee=employee)
user_order,status = Order.objects.get_or_create(owner=user_profile,
is_ordered=False,order_amount=amount)####TThis IS WHWERE TO EDIT TO PREVENT
RE ORDERNG OF FREELANCING
user_order.tasks.add(order_task)
if status:
user_order.ref_code = generate_order_id()
user_order.save()
messages.info(request,"task added to catalogue")
return redirect(reverse('freelance:employee_list'))
def get_user_pending_order(request):
#get order from correct profile
user_profile = get_object_or_404(Profile,user=request.user)
order = Order.objects.filter(owner=user_profile,is_ordered=True)
if order.exists():
#to get an order in the list of filtered orders
return order[0]
return 0
models.py
class Order(models.Model):
ref_code = models.CharField(max_length=15)
owner = models.ForeignKey(Profile, on_delete=models.SET_NULL, null=
True)
is_ordered = models.BooleanField(default=False)
tasks = models.ManyToManyField(OrderTask)
date_ordered = models.DateTimeField(auto_now= True)
order_amount = models.DecimalField(default=0.01, max_digits= 10,
decimal_places=2)
def order_tasks(self):
return ','.join([str(c.employee) for c in self.tasks.all()])
def get_catalogue_tasks(self):
return self.tasks.all()
def get_catalogue_total(self):
return sum([task.employee.pricing for task in self.tasks.all()])
def __str__(self):
return '{0} - {1}'.format(self.owner, self.ref_code, self.order_amount)
def tasks_summary(request):
existing_order = get_user_pending_order(request)
my_user_profile = Profile.objects.filter(user=
request.user).first()
my_orders = Order.objects.filter(is_ordered= True, owner=
my_user_profile)
order_to_purchase = get_user_pending_order(request)
amount= order_to_purchase.get_catalogue_total(),
order = Order.objects.filter(is_ordered= True)
context = {
'my_orders':my_orders,
'order':order,
'amount':amount
# 'total':total,
}
return render(request,
'freelance/tasks_summary.html',context)###Belongs to the admin sisde
Output of the template
I am getting this error when I try to add anything to the catalogue:
AttributeError at /admin/tasks_summary/
'int' object has no attribute 'get_catalogue_total'

ValueError: variable needs to have a value for field "id" before this many to many relationship can be used - Django

I created a datamodel in Django, and now I created a script to auto populate the models using web-scraped values. However when I run the script I get the following error:
ValueError: variable needs to have a value for field "id" before this many to many relationship can be used
Models.py
class Books(models.Model):
title = models.CharField(max_length=100)
def __str__(self):
return self.title
class Meta:
ordering = ['-title']
class Author(models.Model):
book = models.ManyToManyField(Books)
first_name = models.CharField(max_length=150)
last_name = models.CharField(max_length=200)
def __str__(self):
return "{} {}".format(self.first_name, self.last_name)
class Meta:
ordering = ['last_name','first_name']
class Book_details(models.Model):
book = models.ForeignKey(Books,
on_delete=models.CASCADE,
null=True) # models.SET_NULL weggehaald
pages = models.CharField(max_length=250)
publ_year = models.CharField(max_length=250)
edition = models.CharField(max_length=30) # paperback, hardcover, audiobook, etc
def __str__(self):
return "{} - pages: <{}>, edition: <{}>".format(self.book.title,
self.pages,
self.edition)#
class Cover(models.Model):
book = models.OneToOneField(Books,
on_delete=models.CASCADE)
path = models.CharField(max_length=500)
def __str__(self):
return "<Cover <path={}>".format(self.id, self.path)
populate_script
def add_book(title):
b = Books.objects.get_or_create(title = title)[0]
print(b)
b.save()
return b
def populate(scraped_tuple):
fake = Faker()
for _ in range(len(scraped_tuple)):
b_title = scraped_tuple[_][0][0]
new_book = add_book(b_title)
b_author_first = scraped_tuple[_][0][1].split(" ")[0]
b_author_last = scraped_tuple[_][0][1].split(" ")[1]
b_pages = scraped_tuple[_][0][2].split(" ")[0]
b_publ_year = fake.year()
b_edition = scraped_tuple[_][0][3].split(",")[0]
b_cover = scraped_tuple[_][0][4]
new_details = Book_details.objects.get_or_create(book = new_book, pages = b_pages, publ_year = b_publ_year, edition = b_edition)[0]
new_author = Author.objects.get_or_create(book = new_book, first_name = b_author_first, last_name = b_author_last)[0]
new_cover = Cover.objects.get_or_create(book = new_book, path = b_cover)[0]
The scraped_tuple is a return value from the webscraper containing the details.
(Part of) the Traceback:
Books.models.DoesNotExist: Author matching query does not exist.
File "C:\path\to\LibraryApp\Library_WebA
pp\Library\populate.py", line 45, in populate
new_author = Author.objects.get_or_create(book = new_book, first_name = b_author_first, last_nam
e = b_author_last)[0]
Followed by:
ValueError: "<Author: Mary McCarthy>" needs to have a value for field "id" before this many-to-many relationship can be used.
So, it seems that something goes awfully wrong when trying to execute the new_author statement, because of the many-to-many field "book" in the Author model. How can I resolve this. Do I need a similar function for an Author object like I have for the Book in add_book()?
It seems the new_details statement executes just fine (title and book_details appear correctly in the database in the admin part of Django).
As mentioned in the docs, user .add() to associate the records in many to many field.
def populate(scraped_tuple):
fake = Faker()
for _ in range(len(scraped_tuple)):
b_title = scraped_tuple[_][0][0]
new_book = add_book(b_title)
b_author_first = scraped_tuple[_][0][1].split(" ")[0]
b_author_last = scraped_tuple[_][0][1].split(" ")[1]
b_pages = scraped_tuple[_][0][2].split(" ")[0]
b_publ_year = fake.year()
b_edition = scraped_tuple[_][0][3].split(",")[0]
b_cover = scraped_tuple[_][0][4]
new_details = Book_details.objects.get_or_create(book = new_book, pages = b_pages, publ_year = b_publ_year, edition = b_edition)[0]
new_author = Author.objects.get_or_create(first_name = b_author_first, last_name = b_author_last)[0]
# add many to many fields this way:
new_author.book.add(new_book)
new_cover = Cover.objects.get_or_create(book = new_book, path = b_cover)[0]

Django model inserting foreign key from same model

I am building a simple comment app in Django. The app allows replies to comments and uses the same model to store comments and replies. My issues is when I try to insert a new reply, the parentpost(FK to parent comment) inserts as NULL. When I use the admin interface to insert a reply, it properly stores the parentpost ID for the parentpost I choose. So I know the issue is not within my model but within my view.
/MODEL/
class UserPost(models.Model):
name = models.CharField(max_length=50)
slug = models.SlugField(max_length=50, unique=True,
help_text='Unique value for product page URL, created from name.', editable = False)
post = models.TextField()
is_active = models.BooleanField(default=True)
meta_keywords = models.CharField("Meta Keywords", max_length=255, blank = True, null = True,
help_text='Content for description meta tag')
meta_description = models.CharField(max_length = 255, blank = True, null = True,
help_text = 'Content for description meta tag')
created_at = models.DateTimeField(auto_now_add = True)
updated_at = models.DateTimeField(auto_now = True)
parentpost = models.ForeignKey('self', blank = True, null = True)
class Meta:
#app_label = ''
db_table = 'userposts'
ordering = ['created_at']
verbose_name_plural = 'UserPosts'
def __unicode__(self):
return self.name
#models.permalink
def get_absolute_url(self):
return ('lync_posts', (), {'posts_slug': self.slug})
def save(self):
if not self.id:
d = datetime.datetime.now()
s = d.strftime('%Y-%M-%d-%H-%M-%S-%f')
slugfield = str(self.name + s)
self.slug = slugfield
super(UserPost, self).save()
/VIEW/
def reply(request, slugIn):
parentpostIn = UserPost.objects.get(slug = slugIn)
pid = parentpostIn.id
template_name = 'reply.html'
if request.method == 'POST':
form = forms.ReplyPostForm(data = request.POST)
# create a new item
if form.is_valid(): # All validation rules pass
# Process the data in form.cleaned_data
# ...
if form.is_valid():
nameIn = form.cleaned_data['name']
postIn = form.cleaned_data['post']
newPost = UserPost(name = nameIn, post = postIn, parentpost = pid)
newPost.save()
return render_to_response(template_name, locals(), context_instance = RequestContext(request))
else:
# This the the first page load, display a blank form
form = forms.NewPostForm()
return render_to_response(template_name, locals(), context_instance=RequestContext(request))
return render_to_response(template_name, locals(), context_instance=RequestContext(request))
You are trying to set the parentpost ForeignKey by id.
You should either use:
newPost = UserPost(name = nameIn, post = postIn, parentpost = parentpostIn)
or (see Django: Set foreign key using integer?):
newPost = UserPost(name = nameIn, post = postIn)
newPost.parentpost_id = pid

ndb badrequesterror only in production

I get the following error only on production: BadRequestError: BLOB, ENITY_PROTO or TEXT properties must be in a raw_property field
It happens when I put() a instance of the Receipt class (extends ndb.Model)
Below, I attach the model and the handler where the code breaks (only in production)
class Receipt(RModel):
ownerId = ndb.IntegerProperty()
houseId = ndb.IntegerProperty()
renterId = ndb.IntegerProperty()
year = ndb.IntegerProperty()
month_number = ndb.IntegerProperty()
code = ndb.StringProperty()
description = ndb.StringProperty()
value = ndb.StringProperty()
owner = ndb.ComputedProperty(lambda self: Owner.get_by_id(self.ownerId))
house = ndb.ComputedProperty(lambda self: House.get_by_id(self.houseId))
renter = ndb.ComputedProperty(lambda self: Renter.get_by_id(self.renterId))
month = ndb.ComputedProperty(lambda self: month_number_to_string(self.month_number))
class RModel(ndb.Model):
created = ndb.DateTimeProperty(auto_now_add = True)
changed = ndb.DateTimeProperty(auto_now_add = True)
creatorId = ndb.IntegerProperty()
changerId = ndb.IntegerProperty()
#def to_dict(self):
# return ndb.to_dict(self, {'id':self.key().id()})
def set_attributes(self, **attrs):
props = self.properties()
for prop in props.values():
if prop.name in attrs:
prop.__set__(self, attrs[prop.name])
class ReceiptNew(BaseHandler):
def Get(self):
user_id = self.get_user_id()
owner = Owner.get_by_id(user_id)
receipt = Receipt(value="")
houses = list(House.gql("where ownerId = :1", owner.key.id()))
renters = list(Renter.gql("where ownerId = :1", owner.key.id()))
context = {'receipt': receipt, 'houses': houses, 'renters': renters, 'new': True}
self.render_response('receipt-edit.html', **context)
def post(self):
user_id = self.get_user_id()
owner = Owner.get_by_id(user_id)
data = {
'year': self.request.get('year'),
'month': self.request.get('month'),
'house': self.request.get('house'),
'renter': self.request.get('renter'),
'value': self.request.get('value'),
'paid': self.request.get('paid')
}
receipt = Receipt()
receipt.year = int(data.get('year'))
receipt.month_number = int(data.get('month'))
receipt.houseId = int(data.get('house'))
receipt.renterId = int(data.get('renter'))
receipt.value = data.get('value')
receipt.ownerId = owner.key.id()
receipt.put() ##### CODE BREAKS HERE, ONLY IN PRODUCTION
self.redirect('/receipts')
You can't use ComputedProperty to store an entire entity, you need to use KeyProperty.

Resources