First time I am using the managers in django model so problem can be very basic
I try to calculate totals for my Materials model
those totals are stored in different tables like Inventory , PO, SO
For this reason I decided to do the aggregations inside Material model manager
class MaterialInventoryManager(models.Manager):
def total_active_inventory(self):
return self.get_query_set().annotate(total_inventory=Sum('inventory__quantity')).filter(is_active = True)
class Material(models.Model):
version = IntegerVersionField( )
code = models.CharField(max_length=30)
name = models.CharField(max_length=30)
description = models.TextField(null=True, blank=True)
materialuom = models.CharField(max_length=1,
choices=UOM_CHOICES)
creation_time = models.DateTimeField(auto_now_add=True, blank=True)
total_inventory = MaterialInventoryManager()
objects = MaterialInventoryManager()
#with_author
class Inventory(models.Model):
material = models.OneToOneField('item.Material',null=True, blank=True)
# material_UOM = models.OneToOneField('item.UOM_BINUOM',null=True, blank=True)
warehouse_Bin = models.ForeignKey(WarehouseBin)
is_active = models.BooleanField(default=True)
quantity = models.DecimalField(max_digits=8, decimal_places=5)
creation_time = models.DateTimeField(auto_now_add=True, blank=True)
And when I execute from shell Material.total_inventory()
I am getting
What I am doing wrong?
You have typo, it's self.get_queryset() not self.get_query_set().
Django doc about get_queryset().
Related
I have an app that allows users to signup and register for courses (from a 'TrainingInstance' model). These events have names etc and are categorised as Past or Current in the database (in the 'Training' model). When I show the BuildOrderForm in my template, I want only options for Current trainings to be shown in the dropdown menu. How can this be done in Django without javascript or Ajax?
I have the following form in forms.py:
class BuildOrderForm(forms.ModelForm):
class Meta:
model = Order
fields = ['training_registered']
And the following models in models.py:
class Training(models.Model):
""" Model which specifies the training category (name) and whether they are Past or Present"""
YEAR = (
('current', 'current'),
('past', 'past'),
)
name = models.CharField(max_length=200, null=True)
year= models.CharField(max_length=200, null=True, choices=YEAR, default='current')
def __str__(self):
return self.name
class TrainingInstance(models.Model):
""" Creates a model of different instances of each training ( May 2021 etc) """
name = models.CharField(max_length=200, null=True, blank=True)
venue = models.CharField(max_length=200, null=True, blank=True)
training = models.ForeignKey(Training, on_delete= models.CASCADE, null = True)
training_month = models.CharField(max_length=200, null=True, blank=True)
participant_date = models.CharField(max_length=20, null=True, blank=True)
staff_date = models.CharField(max_length=20, null=True, blank=True)
graduation_date = models.CharField(max_length=200, null=True, blank=True)
def __str__(self):
return self.name
class Order(models.Model):
REGSTATUS = (
('registered', 'registered'),
('enrolled', 'enrolled'),
('holding', 'holding'),
('withdrawn', 'withdrawn'),
('waiting', 'waiting'),
)
customer = models.ForeignKey(Customer, on_delete= models.CASCADE, null = True)
training_registered = models.ForeignKey(TrainingInstance, on_delete= models.SET_NULL, blank = True, null = True)
registration_date = models.DateTimeField(null=True,blank=True)
regstatus = models.CharField(max_length=200, null=True, choices=REGSTATUS, default='registered')
def __str__(self):
return self.customer.username
Here is what I have done - which works but I'm also open to feedback about good/bad practice.
class BuildOrderForm(forms.ModelForm):
class Meta:
model = Order
fields = ['training_registered']
def __init__(self,*args,**kwargs):
super (BuildOrderForm,self ).__init__(*args,**kwargs)
self.fields['training_registered'].queryset = TrainingInstance.objects.filter(training__year ="current")
my models.py
class LiveClass_details(models.Model):
standard = models.ForeignKey(LiveClass, on_delete=models.CASCADE)
chapter_details = models.TextField(default='')
mentor_id = models.ForeignKey(Mentor, max_length=30, on_delete=models.CASCADE)
start_time = models.DateTimeField()
end_time = models.DateTimeField()
doubtClass = models.OneToOneField(DoubtClasses, on_delete=models.PROTECT, null=True, blank=True)
isDraft = models.BooleanField(default=True)
ratings = models.FloatField(default=0)
no_of_students_registered = models.IntegerField(default=0)
# registered_students = models.ManyToManyField(RegisteredNames, null=True, blank=True)
no_of_students_attended = models.IntegerField(default=0)
class Meta:
verbose_name_plural = 'LiveClass_details'
class RegisteredNames(models.Model):
name = models.CharField(max_length=100, unique=True)
liveclass_id = models.ForeignKey
I am creating a endpoint where when a user register himself his name will get added to registered_students , so i had made a registered students ManyToMany Field hoping it will get updated when a user is registered but then i understand that it will contain all the names that are present in the RegisteredNames Model meaning names registered across all the liveclasses but i want only the names that are registered for a particular liveclass in the field so i need a array like field which i think is not possible so please help me in improving my logic, how can i achieve it
The documentation and django tutorials are very good: https://docs.djangoproject.com/en/3.2/topics/db/models/ https://docs.djangoproject.com/en/3.2/intro/tutorial02/#creating-models
Your code is very close. You don’t need the many-to-many field, and you need to specify the type of the Foreign key relationship in the RegisteredNames. You can do this:
class LiveClass_details(models.Model):
standard = models.ForeignKey(LiveClass, on_delete=models.CASCADE)
chapter_details = models.TextField(default='')
mentor_id = models.ForeignKey(Mentor, max_length=30, on_delete=models.CASCADE)
start_time = models.DateTimeField()
end_time = models.DateTimeField()
doubtClass = models.OneToOneField(DoubtClasses, on_delete=models.PROTECT, null=True, blank=True)
isDraft = models.BooleanField(default=True)
ratings = models.FloatField(default=0)
no_of_students_attended = models.IntegerField(default=0)
class Meta:
verbose_name_plural = 'LiveClass_details'
class RegisteredNames(models.Model):
name = models.CharField(max_length=100, unique=True)
liveclass = models.ForeignKey(LiveClass_details, on_delete=Models.CASCADE)
Then, simply:
name = RegisteredNames.objects.create(name="Dhruv", liveclass_id=1)
To get all the registered names from a liveclass_details:
names = LiveClass_details.objects.get(id=1).registerednames_set.all()
num_reg = len(names)
I created a form with the model form manager. Before saving my TransactionProfile ModelForm, I want to connect it with an order model. When I print session_order_id it is the correct id, however self.order_set.get is always empty when I print it in the console. Anyone can help me with that? Would you in general solve it the way I did it here, or ist there a more clean method?
In my views.py I have the following:
t = transaction_profile.save(commit=False)
t.update_order_with_transaction_profile(session_order_id)
t.save()
transactions/models.py
class TransactionProfile(models.Model):
email = models.EmailField()
address_line_1 = models.CharField(max_length=120)
address_line_2 = models.CharField(max_length=120, null=True, blank=True)
city = models.CharField(max_length=120)
country = models.CharField(max_length=120)
state = models.CharField(max_length=120)
postal_code = models.CharField(max_length=120)
update = models.DateTimeField(auto_now=True)
timestamp = models.DateTimeField(auto_now_add=True)
customer_id = models.CharField(max_length=120, null=True, blank=True)
def update_order_with_transaction_profile(self, session_order_id):
# In ModelManager or just in class TransactionProfile
o = self.order_set.get(order_id=session_order_id)
o.transaction_profile = self
o.save()
orders/models.py
class Order(models.Model):
order_id = models.CharField(max_length=10, unique=True)
customer_key = models.CharField(max_length=10, unique=True)
updated = models.DateTimeField(auto_now=True)
timestamp = models.DateTimeField(auto_now_add=True)
transaction_profile = models.ForeignKey(TransactionProfile, blank=True, null=True, on_delete=models.CASCADE)
You need to save object to DB before using it as foreign key. Since in your code t is not saved in DB, update_order_with_transaction_profile will not work.
Instead of self.order_set, which gives you only orders related to specific profile(empty list for new object), you can directly query on Order model, note you need to save transaction_profile firts:
t = transaction_profile.save()
t.update_order_with_transaction_profile(session_order_id)
def update_order_with_transaction_profile(self, session_order_id):
# In ModelManager or just in class TransactionProfile
o = Order.objects.get(order_id=session_order_id)
o.transaction_profile = self
o.save()
I have been working on a model for tags and am trying to avoid using contenttypes. I have couple questions related to ManyToManyField in django.
I have the following model
taggables/models.py
class Tag(models.Model):
tag_statuses = (
(u'P', _('Pending approval')),
(u'A', _('Approved')),
)
slug = models.SlugField()
created_at = models.DateTimeField(null=True, blank=True)
created_by = models.ForeignKey(User, related_name='tagged_item_created_by')
status = models.CharField(max_length=20, choices=tag_statuses)
site = models.ForeignKey(Site, default=settings.SITE_ID, related_name='tagged_item_site')
def __unicode__(self):
return self.slug
class TagI18n(models.Model):
tag = models.CharField(max_length=100)
descriptor = models.TextField(null=True, blank=True)
# i18n properties
item = models.ForeignKey(Tag)
language = models.CharField(max_length=6, choices=settings.LANGUAGES, default=settings.LANGUAGE_CODE)
class Meta:
unique_together = (("language", "item"))
def __unicode__(self):
return self.tag
I also have different apps around my project that uses tag model as many to many field. such as events for example
evetns/models.py
class Item(models.Model):
event_status_list = (
(u'P', _('Pending approval')),
(u'A', _('Approved')),
(u'R', _('Rejected')),
(u'S', _('Spam')),
)
published_at = models.DateTimeField(null=True, blank=True)
published_by = models.ForeignKey(User, null=True, blank=True, related_name='item_published_by')
updated_by = models.ForeignKey(User, null=True, blank=True, related_name='item_updated_by')
updated_at = models.DateTimeField(null=True, blank=True)
site = models.ForeignKey(Site, default=settings.SITE_ID, related_name='events_item_site')
event_slug = models.SlugField(null=True, blank=True)
# event timing
event_start_date = models.DateField()
event_start_time = models.TimeField(null=True, blank=True)
event_end_date = models.DateField()
event_end_time = models.TimeField(null=True, blank=True)
event_recurrent = models.BooleanField(default=False)
event_status = models.CharField(max_length=20, choices=event_status_list, default=u'P')
# relations
media = models.ManyToManyField(ImageFile, null=True, blank=True)
comments = models.ManyToManyField(Comment, null=True, blank=True)
votes = models.ManyToManyField(Vote, null=True, blank=True)
tags = models.ManyToManyField(Tag, null=True, blank=True)
audience = models.ManyToManyField(Audience, null=True, blank=True)
Now what am trying to do here is run a query to programmatically retrieve all the related models to Tag and then count how many a times a tag was used. Am sure I can do that with contenttypes (generic types) but I don't know how it will perform under heavy usage that's why I wanted to do the many to many fields.
If you are interested in the total number of usage ( aka reference count ) of a tag very often, I think you should store it in the database, example put one extra field to the Tag model, like
referencecount = models.IntegerField( default=0 )
Than in the appropriate places, ( example models .save() )you can increment or decrements it's value.
For your use case, the performance of generic wouldn't matter, because you need anyway to do N queries over 2N tables (one for each "taggable" model and one for each m2m join table, at least).
With the m2m approach, you should have the list of 'taggable' models stored somewhere, at least as a list of ('app_name', 'model') pairs. Then use ContentType (it's very performant) to get the actual model class or query directly from there:
counts = {}
for m in taggable_models:
ct = ContentType.get_by_natural_key(*m)
c = ct.model_class().objects.filter(tags=yourtag).distinct().count()
counts[ct.name] = c
I am working on a project and a student of Web Development.
I am making an application in Django. When a user creates a new trip with a form I've made, I want to add a map to that form so that users only have to click a point on a map in order to get coordinates to save to the database for that trip.
I want to save coordinates for every new trip so that I can render a map on each user's profile page that shows them markers of every trip they've taken that is in the database.
Please help!
Thank you
Here's some code:
models.py
class Trip (models.Model):
user = models.ForeignKey(User, on_delete = models.CASCADE, related_name='trips')
start_date = models.DateField()
end_date = models.DateField()
trail = models.CharField(max_length=300)
permit = models.URLField(blank=True, null=True)
completed = models.BooleanField(default=False)
location = models.CharField(blank=True, max_length=400)
lat = models.DecimalField(blank=True, null=True, max_digits=9, decimal_places=6)
lng = models.DecimalField(blank=True, null=True, max_digits=9, decimal_places=6)
created_at = models.DateField(auto_now_add =True)
def __str__ (self):
return self.trail
def total_days(self):
return (self.end_date - self.start_date).days
forms.py
class CreateTrip(forms.ModelForm):
start_date = forms.DateField(
widget=forms.TextInput(
attrs={'type': 'date'}
)
)
end_date = forms.DateField(
widget=forms.TextInput(
attrs={'type': 'date'}
)
)
class Meta():
model = models.Trip
fields = ('trail','location', 'permit', 'completed', 'start_date', 'end_date')
Sounds like to me you have a couple of many-to-one relationships you want to store in your database. My answer is based on this documentation:
https://docs.djangoproject.com/en/2.1/topics/db/examples/many_to_one/
You have Users that can go on many trips.
So you'd have a model called Trip that would look something like:
class Trip(models.Model):
name = models.CharField(max_length=100)
create_date = models.DateTimeField(auto_now_add=True)
user = models.ForeignKey(User)
... whatever else ...
And your trips have points so you might want a model like this:
class Point(models.Model):
lat = models.DecimalField(blank=True, null=True, max_digits=9, decimal_places=6)
lng = models.DecimalField(blank=True, null=True, max_digits=9, decimal_places=6)
order = models.IntegerField() # ordering for the points.
create_date = models.DateTimeField(auto_now_add=True)
trip = models.ForeignKey(Trip)
... whatever else ...