Django Update Multiple Object error - django

i found some problem when i try to update multiple object in my models. here is my models:
class NumberSequence(models.Model):
code = models.CharField(max_length=12)
name = models.CharField(max_length=60)
prefix = models.CharField(max_length=3)
length = models.IntegerField()
last = models.IntegerField(verbose_name='Last Number Used')
def getNumberSequence():
ns = NumberSequence.objects.filter(code='REQ')
letter = ns[0].prefix
lastNumber = ns[0].last+1
l = '{0}-{1:0'+str(ns[0].length)+'d}'
for num in ns:
num.last = lastNumber
num.save()
return l.format(letter,lastNumber+1)
class Requisitions(models.Model):
number = models.CharField(max_length=20, default=getNumberSequence())
transDate = models.DateField(verbose_name='Date')
businessUnit = models.ForeignKey(BusinessUnit, verbose_name='Unit')
division = models.ForeignKey(Division, verbose_name='Division')
remarks = models.TextField
status = models.IntegerField(verbose_name='Status')
when i create new record in Requisition, the table Number Sequence does not update. but if i restart the service, the number sequence table updated automatically.
what's happened with my code?
any suggestion, please..

You should not call the default function in your field definition, but pass the callable only without parentheses.
number = models.CharField(max_length=20, default=getNumberSequence)

Related

get value in table manytomany django

hi I am trying to get the same value in a many to many tables but I don't know how can I achieve that
here is my model:
class Raza(models.Model):
Nombre = models.CharField(max_length=50)
Origen = models.CharField(max_length=45)
Altura = models.CharField(max_length=10)
Peso = models.CharField(max_length=10)
Esperanza_vida = models.CharField(max_length=10)
Actividad_fisica = models.CharField(max_length=45)
Recomendaciones = models.CharField(max_length=500)
Clasificacion_FCI = models.ForeignKey(Clasificacion_FCI,null=True,blank=True,on_delete=models.CASCADE)
Tipo_pelo = models.ManyToManyField(Tipo_pelo,blank=True)
Caracteristicas_fisicas = models.ManyToManyField(Caracteristicas_fisicas,blank=True)
Caracter = models.ManyToManyField(Caracter,blank=True)
Ideal = models.ManyToManyField(Ideal,blank=True)
Tamanio = models.ForeignKey(Tamanio,null=True,blank=True,on_delete=models.CASCADE)
User = models.ManyToManyField(User,blank=True)
I am using the User model that's provided by Django
I have no idea how can I do that
I want do something like that
table user
id_usuario = 1
name = "Juan"
table raza
id_raza = 1
name = "pitbull"
table user_raza
id_user_raza = 1
id_user = 1
id_raza = 1
Please write class attributes with small letters in python.
to your question:
raza = Raza.objects.get(id=1)
tipo_pelos = raza.tipo_pelo.all()
for tp in tipo_pelos:
print(tp.id)
...
...
Django has wonderful documentation for this. Have fun.

Error update formatted sequence number table

i have code like this:
class NumberSequence(models.Model):
code = models.CharField(max_length=12)
prefix = models.CharField(max_length=3, verbose_name='Prefix')
length = models.IntegerField(verbose_name='Digit Length')
last = models.IntegerField(verbose_name='Last Number Used')
def getNumberSequence():
ns = NumberSequence.objects.filter(code='REQ')
letter = ns[0].prefix
lastNumber = ns[0].last+1
formatedNS = '{0}-{1:0'+str(ns[0].length)+'d}'
NumberSequence.objects.filter(code='REQ').update(last=lastNumber)
return formatedNS.format(letter,lastNumber)
class Requisitions(models.Model):
number = models.CharField(max_length=20, default=getNumberSequence)
but when I created new record in Requisition, the last number in NumberSequence updated to lastNumber+2.
example : last = 1. When i created new record, last updated to 3. The last should be updated to 2.
What's wrong with my code? Thanks

Building up subqueries of derived django fields

I have a few transformations I need to perform on my table before I aggregate.
I need to multiply transaction_type (which is either 1 or -1) by amount to yield a signed_amount. Then I need to sum all signed_amounts by primary_category (which is a foreign key to secondary category which is a foreign key of my table).
DEBIT = -1
CREDIT = 1
TRANSACTION_TYPE_CHOICES = (
(DEBIT, 'debit'),
(CREDIT, 'credit'),
)
class Transaction(models.Model):
amount = models.DecimalField(max_digits=7, decimal_places=2)
transaction_type = models.IntegerField(choices=TRANSACTION_TYPE_CHOICES)
secondary_category = models.ForeignKey(Secondary_Category)
class Primary_Category(models.Model):
name = models.CharField("Category Name", max_length=30)
category = models.ForeignKey(Primary_Category_Bucket)
class Secondary_Category(models.Model):
name = models.CharField("Category Name", max_length=30)
primary_category = models.ForeignKey(Primary_Category)
I'm stuck on the first bit though.
from django.db.models import Sum, Count, F
original_transactions = Transaction.objects.all()
original_transactions.signed_amount = F('transaction_type') * F('amount')
for transaction in original_transactions:
print transaction.signed_amount
When I try to sanity check that signed_amount is being calculated, I get an error that 'Transaction' object has no attribute 'signed_amount'. I don't want to save signed_amount to the database. I just want to generate it as derived field so I can calculate my totals.
How do I calculate this derived field and subsequently aggregate by primary_category.name?
User python decorator property on a method for class Transaction:
class Transaction(models.Model):
amount = models.DecimalField(max_digits=7, decimal_places=2)
transaction_type = models.IntegerField(choices=TRANSACTION_TYPE_CHOICES)
secondary_category = models.ForeignKey(Secondary_Category)
#property
def signed_amount(self):
return self.amount * self.transaction_type
Then for each Transaction object you can do transaction.signed_amount.
I'm not sure if the aggregation part could be done using queries, but if you don't have that many PrimaryCategory, then python would be good enough to achieve it.
Or you can do this.
all_transactions = Transaction.objects.all().order_by('secondary_category__primary_category_id')
sum = 0
if all_transactions:
primary_category_id = all_transactions[0].secondary_category.primary_category_id
for transaction in all_transactions:
if primary_category_id == transaction.secondary_category.primary_category_id:
sum += (transaction.amount * transaction_type)
else:
sum = (transaction.amount * transaction_type)
print sum

Django queryset search on multiple models, return the same object

I'm trying to create an advanced search on my website, you are looking at various models related to each one, always returning a list of profiles that meet some parameters
Here are my Models:
class Profile(models.Model):
first_name=models.CharField(max_length=60, blank=False)
last_name=models.CharField(max_length=60, blank=False)
residence=models.CharField(max_length=60, null=True, blank=True)
birthdate=models.DateField(null=True, blank=True)
telephone=models.CharField(max_length=60, null=True, blank=True)
email=models.EmailField(null=True, blank=True)
linkedin=models.URLField(null=True, blank=True)
starred=models.BooleanField(default=False)
created_from = models.ForeignKey(EmployeeUser, related_name='profile_author')
created_on = models.DateField(default=tznow)
internal_id = models.CharField(max_length=5, blank=True)
class Education(models.Model):
almalaurea_id = models.CharField(max_length=60, null=True, blank=True)
profile = models.ForeignKey(Profile, related_name='education_profile')
education_type = models.ForeignKey(Education_type, related_name='education_type')
class Education_type(models.Model):
VALUES = (
(0, 'Altro'),
(1, 'Licenza media'),
(2, 'Diploma'),
(3, 'Laurea Triennale'),
(4, 'Laurea Magistrale'),
)
title = models.CharField(max_length=60)
value = models.IntegerField(choices=VALUES)
I want to search the profiles that meet various results, such as birthdate, residence, starred, education (based on education_type)
This is an example scenario, my research includes other models
These are the research in my view, I thought that having found the results of the two queries, I could extract the profile id and compare them, then run another query by selecting profiles that match, but I think it's not a great idea, the real scenario includes other various models.
filters_profile = []
filters_education = []
year = form.cleaned_data["year"]
residence = form.cleaned_data["residence"]
starred = form.cleaned_data["starred"]
education_type = form.cleaned_data["education_type"]
if year:
filters_profile.append(Q(birthdate__year=year))
if residence:
filters_profile.append(Q(residence__icontains=residence))
if starred:
filters_profile.append(Q(starred=starred))
result_profile = Profile.objects.filter(reduce(lambda q1, q2: q1 & q2, filters_profile)).order_by('first_name')
result_education = None
if education_type:
e = Education_type.objects.filter(title=education_type)
result_education = Education.objects.filter(education_type=e).prefetch_related('profile','education_type')
Any idea?
Many thanks in advance :)
EDIT :
About the solution of #Geo Jacob
Here is the third models:
if valutation:
result_valutation = Status.objects.filter(valutation=valutation).values_list('profile_id', flat=True)
key['id__in'] = result_valutation
Adding this code for my scenario, this solution don't work, as i written in the comments :)
"in practice, the content of key['id__in'] is overwritten when the other model query (this) is executed"
Try this:
key = {}
year = form.cleaned_data["year"]
residence = form.cleaned_data["residence"]
starred = form.cleaned_data["starred"]
education_type = form.cleaned_data["education_type"]
if year:
key['birthdate__year'] = year
if residence:
key['residence__icontains'] = residence
if starred:
key['starred'] = starred
if education_type:
e = Education_type.objects.filter(title=education_type)
result_education = Education.objects.filter(education_type=e).values_list('profile_id', flat=True)
key['id__in'] = result_education
result_profile = Profile.objects.filter(**key).order_by('first_name')
My solution working on more than 2 models, based on #Geo Jacob solution, thank you
I make a check and put in key['id__in'] only matched id from the previous query, so as to intersect the results
key = {}
statokey = 0
year = form.cleaned_data["year"]
residence = form.cleaned_data["residence"]
starred = form.cleaned_data["starred"]
education_type = form.cleaned_data["education_type"]
valutation = form.cleaned_data["valutation"]
if year:
key['birthdate__year'] = year
if residence:
key['residence__icontains'] = residence
if starred:
key['starred'] = starred
if education_type:
e = Education_type.objects.filter(title=education_type)
result_education = Education.objects.filter(education_type=e).values_list('profile_id', flat=True)
if statokey > 0:
for r in result_education:
for k in key['id__in']:
if r == k:
key['id__in'] = str(r)
else:
key['id__in'] = result_education
statokey += 1
if valutation:
result_valutation = Status.objects.filter(valutation=valutation).values_list('profile_id', flat=True)
if statokey > 0:
for r in result_valutation:
for k in key['id__in']:
if r == k:
key['id__in'] = str(r)
else:
key['id__in'] = result_valutation
statokey += 1
result_profile = Profile.objects.filter(**key).order_by('first_name')

TypeError: add() argument after * must be a sequence, not Subscribers

class Subscribers(User):
date = models.DateField()
user = models.OneToOneField(User)
class Tour(models.Model):
owner_id = models.ForeignKey(User)
name = models.CharField(max_length=50)
location = models.ManyToManyField(Location)
subscribers = models.ManyToManyField(Subscribers, related_name="sub")
I am trying to do this in another file:
user1 = User.objects.create_user('John','j#j.com','j1')
user2= User.objects.create_user('Mike','m#m.com','m1')
user3= User.objects.create_user('kokoko','m#m.com','m1')
user4= User.objects.create_user('lalal','m#m.com','m1')
sub = Subscribers()
tour = Tour()
tour.id = "1"
tour.name = "hello"
tour.owner_id = user1
tour.subscribers = sub
but I have this error:
TypeError: add() argument after * must be a sequence, not Subscribers
The ManyToMany manager assumes that when you do
tour.subscribers = sub
sub is a sequence (tuple, list, queryset) of Subscribers, not a single object. Then doing so is the exact same as doing:
tour.subscribers.add(*sub)
And since sub is not a sequence, it throws such error. I would recommend saving first and adding later. I think it's also more readable, but it may be just my opinion:
sub = Subscribers()
tour = Tour()
tour.id = "1"
tour.name = "hello"
tour.owner_id = user1
tour.save()
tour.subscribers.add(sub)
Hope this helps :)