I wrote a simple string generator for my order_id field.
I tested the generator script in shell, and it works perfectly.
But when I run the server, and try to create an order in django admin, the order id field remains empty when I click save.
What am I doing wrong?
from datetime import date
from django.db import models
from django.db.models.signals import pre_save
from cartapp.models import Cart
class Order(models.Model):
order_id = models.CharField(max_length=120)
cart = models.ForeignKey(Cart, on_delete=models.CASCADE)
status = models.CharField(max_length=50, default='Waiting', null=True, blank=True)
order_total = models.DecimalField(default=0.0, max_digits=10, decimal_places=1)
date_created = models.DateTimeField(auto_now_add=True)
def order_id_generator(instance):
today = date.today().strftime("%Y-%m-%d")
last_order_raw = Order.objects.latest('order_id').date_created
last_order_date = str(last_order_raw).split(' ')[0]
if today != last_order_date:
new_order_id = str(today + " 1")
else:
last_order = Order.objects.latest('order_id')
extract = last_order.order_id.split(' ')[1]
increment = int(extract) + 1
new_order_id = today + " " + str(increment)
return new_order_id
def pre_save_order_id(sender, instance, *args, **kwargs):
if not instance.order_id:
instance.order_id = order_id_generator(instance)
pre_save.connect(pre_save_order_id, sender=Order)
I noticed that you are passing instance to order_id_generator but doesn't use it there. You can avoid using signals and you can use your function as the model field default:
class Order(models.Model):
order_id = models.CharField(max_length=120, default=order_id_generator)
and you doesn't need an arg instance in your function:
def order_id_generator():
today = date.today().strftime("%Y-%m-%d")
last_order_raw = Order.objects.latest('order_id').date_created
last_order_date = str(last_order_raw).split(' ')[0]
if today != last_order_date:
new_order_id = str(today + " 1")
else:
last_order = Order.objects.latest('order_id')
extract = last_order.order_id.split(' ')[1]
increment = int(extract) + 1
new_order_id = today + " " + str(increment)
return new_order_id
Related
My model:
class VisData(models.Model):
visdata_id = models.AutoField(primary_key=True,blank=True)
user_name = models.ForeignKey(Customer, null=True, on_delete=models.SET_NULL,blank=True)
title = models.CharField(max_length=200, null=True,blank=True)
buy_sell = models.CharField(max_length=1, null=True,blank=True)
date = models.DateField(auto_now_add=False,null=True,editable=True,blank=True)
hour = models.TimeField(auto_now=False, auto_now_add=False,null=True,editable=True,blank=True)
shares_number = models.DecimalField(decimal_places=0,default=0,max_digits=999,null=True,blank=True)
course = models.DecimalField(decimal_places=2,default=0,max_digits=999,null=True,blank=True)
fare = models.DecimalField(decimal_places=2,default=0,max_digits=999,null=True,blank=True)
def __str__(self):
return self.title
I want to assign:
total_value = (shares_number * (course - fare)) and just print it in terminal
My views:
def summaryPage(request):
visdata = VisData.objects.all()
#print(visdata)
context = {}
return render(request, 'smth/homepage.html', context)
I found some close answers but I couldn't understand the solution nor use them in my code.
What you probably need called aggregation:
from django.db.models import F, Sum
def summaryPage(request):
aggregated_data = VisData.objects.annotate(
intermid_result=F('course') - F('fare')
).annotate(
record_total=F('shares_number') * F('intermid_result')
).aggregate(
total=SUM('record_total')
)
result = aggregated_data['total']
print(result)
...
This query will annotate each record with the value of record_total = shares_number * (course - fare) and then calculate a sum for record_total of all records.
Also try to avoid using camelcase function names in Python. See here for details.
I'm trying to duplicate multiple data I only need to change their related foreignkeymy problem is that I'm able to duplicate but with the same foreignkey below is my code
any suggestions please
from django.db import models
class Category(models.Model):
category_name = models.CharField(max_length=100)
def __str__(self):
return self.category_name
class Client(models.Model):
cat = models.ForeignKey(Category, on_delete=models.CASCADE, null=True, blank=True)
fname = models.CharField(max_length=100)
lname = models.CharField(max_length=100)
age = models.IntegerField()
married = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.fname + " " + self.lname + " " + str(self.cat)
def show_category(request, cat_id):
clients = Client.objects.filter(cat__id=cat_id)
if request.method =='POST':
for i in clients:
i.id = None
i.cat.id=3
i.save()
return redirect('/')
context = {'clients':clients}
return render(request, 'app/home_cat.html', context)
See the documentation on copying model instances:
def change_category(clients, new_category_id):
for client in clients:
client.pk = None
client._state.adding = True
client.cat_id = new_category_id
client.save()
How to load image to bd, well i generate qr image(QRcode)when she is generated, i need to create a new record in bd, to save this image and code himslef
This is my model
class QRCode(models.Model):
user = models.ForeignKey(UserProfile, blank=True, default=None)
qr_code = models.CharField(max_length=120)
qr_code_img = models.ImageField(upload_to="qr_code_img/", width_field="width_field", height_field="height_field")
upcoming_show = models.ForeignKey(SectionUpcomingShow)
width_field = models.IntegerField(default=270)
height_field = models.IntegerField(default=270)
is_active = models.BooleanField(default=True)
timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)
updated = models.DateTimeField(auto_now_add=False, auto_now=True)
def __str__(self):
return "{0} - - {1}".format(self.user.username, self.is_active)
class Meta:
ordering = ["-timestamp"]
verbose_name = 'QRCode'
verbose_name_plural = 'QRCodes'
#property
def image_path(self):
return os.path.abspath(self.qr_code_img)
this is view to gen qrimg
def qr_code_generator(hex_code, username, __show__id, __show__name__, __show__q, price):
qr_code_generate_himslef = pyqrcode.create(hex_code)
generate_name = ''.join(username + '_' + str(__show__id) + '_' + __show__name__ + '_' + str(__show__q) + '_' + str(price) + '.png').replace(" ", "_")
qr_code_generate_himslef.png(generate_name, scale=6)
print(qr_code_generate_himslef)
return qr_code_generate_himslef
when i print this function i got this
QRCode(content=b'f40a03cb6026d68f0f83c43b47c9e388ed106848', error='H', version=5, mode='binary')
this is my save view
new_qr_code, created = QRCode.objects.get_or_create(user=get_user_profile, qr_code=hex_code, is_active=True, defaults={"user":get_user_profile, "qr_code":hex_code, "qr_code_img":qr_img, "upcoming_show":get_upcoming_show})
if not created:
pass
when you run this function
def qr_code_generator(hex_code, username, __show__id, __show__name__, __show__q, price):
qr_code_generate_himslef = pyqrcode.create(hex_code)
generate_name = ''.join(username + '_' + str(__show__id) + '_' + __show__name__ + '_' + str(__show__q) + '_' + str(price) + '.png').replace(" ", "_")
qr_code_generate_himslef.png(generate_name, scale=6)
print(qr_code_generate_himslef)
return qr_code_generate_himslef
the qr_code image file will be produced in your root directory(the directory having your manage.py file) with the name 'generate_name' variables value.
then open that image like
import os
from django.core.files import File
with open(generate_name, 'rb') as qr_img:
new_qr_code, created = QRCode.objects.get_or_create(user=get_user_profile, qr_code=hex_code, is_active=True, defaults={"user":get_user_profile, "qr_code":hex_code, "qr_code_img":File(qr_img), "upcoming_show":get_upcoming_show})
if not created:
pass
and your qr_image will be uploaded to your 'upload_to' location given in models field. you can put this code in try block to avoid exceptions.
you can then remove the useless qr code image generated by that function
os.remove(generate_name)
hope it helps...
Here is my models.py file.
from django.db import models
from django.contrib.auth.models import User
class image(models.Model):
name = models.CharField(max_length = 200)
src = models.URLField()
alt = models.CharField(max_length = 200)
points = models.IntegerField(default = 0)
id = models.CharField(max_length = 200, primary_key = True)
hotelId = models.IntegerField()
def __unicode__(self):
return self.name
class imagescore(models.Model):
user = models.ForeignKey(User)
image_id = models.CharField(max_length = 200)
score = models.IntegerField(default = 1)
createdTime = models.DateTimeField(auto_now_add =True)
def __unicode__(self):
if self.score < 0:
status = " rejected "
else:
status = "approved"
return (self.user+ status+ image_id)
pass
I would like to pass on to my template a table that is a result of the SQL Query:
select ei.id,ei.src, ei.hotelId , sum(score)
from eyeballing_image ei LEFT join eyeballing_imagescore eis on ei.id = eis.image_id
where user_id = request.user.id and ei.hotelId = 56565
group by
ei.id,ei.src, ei.hotelId
My app name is eyeballing. O tried using joins and filters bot i couldn't make it work.
Additionally, i tried making the sum(score) part into a separate dict and check the same in the template. Didn't work
Any help will be appreciated.
Your query has two problems, one in column name hotelId. you must use it in query in this way ei."hotelId".
Other problem is in condition user_id = request.user.id because you have not request in sql and you must replace it with a value.
Maybe another problem is in return (self.user + status + image_id) that must be return (self.user + self.status + self.image_id).
if "allotted_pto" (paid time off) is an integer field (expressing number of days) in a UserProfile model:
class UserProfile(models.Model):
user = models.ForeignKey(User, unique=True)
fullname = models.CharField(max_length=64, unique=False)
company = models.CharField(max_length=50, choices=CLIENT_CHOICES)
...
allotted_pto = models.IntegerField(max_length=2, blank=True, null=True)
...
User.profile = property(lambda u: UserProfile.objects.get_or_create(user=u)[0])
and "total_days" returns an integer from a vacation request model:
class LeaveRequest(models.Model):
employee = models.ForeignKey(UserProfile)
supervisor = models.ForeignKey(UserProfile, related_name='+', blank=False, null=False)
...
total_days = models.IntegerField(max_length=2, blank=True, null=True)
def __unicode__ (self):
return u'%s %s' % (self.employee, self.submit_date)
def save(self, *args, **kwargs):
fromdate = self.start_date
todate = self.return_date
daygenerator = (fromdate + timedelta(x + 1) for x in xrange((todate - fromdate).days))
self.total_days = sum(1 for day in daygenerator if day.weekday() < 5)
super(LeaveRequest, self).save(*args, **kwargs)
...
how can I construct a view that gives me the sum of "total_days" from a filter set of records and subtract that sum from the "allotted_pto" in the user profile? The simple view I wrote (see below) produces the number of "total_days" objects (in dictionary form) as opposed to counting the actual days, and the request for "allotted_pto" is apparently incorrectly constructed because it returns nothing at all...
#views.py
def leave_screen(request, id):
profile = UserProfile.objects.get(user=id)
records = LeaveRequest.objects.filter(employee=id)
agg_pto = LeaveRequest.objects.aggregate(Count('total_days'))
if profile.allotted_pto: #if the allotted_pto field in UserProfile is not empty
allotted_pto = profile.allotted_pto
remaining_pto = allotted_pto - agg_pto
else:
remaining_pto = "na"
return render_to_response("vacation/leave_request.html", {'records': records, 'agg_pto': agg_pto, 'remaining_pto': remaining_pto})
ok, figured out calculation:
def leave_screen(request, id):
...
agg_pto = LeaveRequest.objects.filter(employee=id).aggregate(Sum('total_days'))
agg_pto = agg_pto['total_days__sum']
just have to figure out how to pull the allotted_pto integer from the User Profile model.
ok, so this wasn't as difficult as I thought. The first challenge was to get an aggregate sum of objects. My first attempt was close but I should have just used "Sum" as opposed to "Count":
agg_pto = LeaveRequest.objects.filter(employee=id).aggregate(Sum('total_days'))
then I just used the python method for extracting the value from a dictionary:
agg_pto = agg_pto['total_days__sum']
finally:
def leave_screen(request, id):
user = request.user.id
profile = request.user.get_profile()
records = LeaveRequest.objects.filter(employee=id).order_by('-submit_date')
agg_pto = LeaveRequest.objects.filter(employee=id).aggregate(Sum('total_days'))
agg_pto = agg_pto['total_days__sum']
allotted_pto = profile.allotted_pto
if allotted_pto: #if the allotted_pto field in UserProfile is not empty
remaining_pto = allotted_pto - agg_pto
else:
remaining_pto = "na"
supervised_records = LeaveRequest.objects.filter(supervisor=id).order_by('-submit_date')
return render_to_response("vacation/leave_request.html", {'records': records, 'supervised_records': supervised_records, 'agg_pto': agg_pto, 'allotted_pto': allotted_pto, 'remaining_pto': remaining_pto, 'profile': profile })
I don't know why it was so hard for me to figure out the syntax for pulling objects from the UserProfile. But I do know that the django-debug-toolbar is very helpful.