Django NameError while using Q object - django

I using Q object as for search,
tracks_list = Track.objects.order_by("rating")
query = request.GET.get("search")
if query:
tracks_list = tracks_list.filter(
Q(title__icontains(query))|
Q(genres__name__icontains(query))
).distinct()
and my models are described as,
class Track(models.Model):
title = models.CharField(max_length=128)
genres = SortedManyToManyField(Genre)
rating = models.IntegerField(default=0, validators=[MaxValueValidator(10), MinValueValidator(0)])
class Genre(models.Model):
name = models.CharField(max_length=128, unique=True, null='False')
views = models.IntegerField(default=0)
slug = models.SlugField(unique=True)
Yet I am receiving a NameError stating global name 'title__icontains' is not defined

you need
title__icontains=query
instead of
title__icontains(query)
the same applies for genres__name__icontains

Related

Retrieve items from Many-to-Many relationship in Django query

Models.py
class SalesOrderItems(models.Model):
item = models.ForeignKey(MasterItems, on_delete=models.CASCADE)
item_quantity = models.IntegerField(default=0)
class SalesOrder(models.Model):
delivery_method_choice = (('Full-Truck Load', 'Full-Truck Load'), ('Part-Truck Load', 'Part-Truck Load'))
status_choices = (('On Hold', 'On Hold'),('Ready to Dispatch', 'Ready to Dispatch'),('Dispatched', 'Dispatched'))
owner = models.ForeignKey(Teacher, on_delete=models.CASCADE, related_name='so_owner')
client = models.ForeignKey(MasterClient, on_delete=models.CASCADE, related_name='so_client')
reference_no = models.CharField(max_length=500, blank=True, null=True)
date = models.DateField(default=datetime.date.today)
shipment_date = models.DateField(default=datetime.date.today)
delivery_method = models.CharField(max_length=500, default='Full-Truck Load', choices=delivery_method_choice)
items = models.ManyToManyField(SalesOrderItems, related_name='items_so', blank=True, null=True)
status = models.CharField(max_length=500, default='On Hold', choices=status_choices)
origin = models.CharField(max_length=255)
destination = models.CharField(max_length=255)
I want to retrieve the items of a particular sales order by django query
My attempt to get the items:
items = []
for i in sales_orders:
so = SalesOrder.objects.filter(pk=i)[0]
print("items",so.items)
Output:
items classroom.SalesOrderItems.None
How can I get the list of items in a particular SalesOrder ??
sales_orders = SalesOrder.objects.prefetch_related('items').filter(**sales_filter_here)
for sales_order in sales_orders:
for sales_order_item in sales_order.items.all():
print(sales_order_item)
this query will work for you
SalesOrder.objects.filter(id=1).values_list('items__item__item_name')
below is my simple Masteritems model
class MasterItems(models.Model):
item_name = models.CharField(max_length=50)
def __str__(self):
return self.item_name
by this way you will get every item name in queryset. this is my simple output
<QuerySet [('rice',), ('pepsi',), ('Computer',)]>

Django : Create custom object list in the view and pass it to template to loop over

I want to create a custom object list in the view and pass it to the template. In the template I want to loop over the list and display the information.
My models are
class CustomUser(AbstractUser):
def __str__(self):
return self.email
class Post(models.Model):
author = models.ForeignKey(CustomUser,on_delete=models.CASCADE,)
text = models.TextField()
created_date = models.DateTimeField(default=timezone.now)
published_date = models.DateTimeField(blank=True, null=True)
post_url = models.URLField(max_length = 200, blank = True)
slug = models.SlugField(unique=True, blank=True)
class subscription(models.Model):
creator = models.ForeignKey(CustomUser,default=None, null=True,on_delete=models.CASCADE,related_name='creator',)
booster = models.ForeignKey(CustomUser,default=None, null=True,on_delete=models.CASCADE,related_name='booster')
sub_value = models.FloatField(blank = True)
sub_id = models.TextField(blank = True)
status = models.BooleanField(default=False)
dateSubscribed = models.DateTimeField(default=timezone.now)
dateSubscriptionEnded = models.DateTimeField(default=timezone.now)
paymentCount = models.FloatField(default= 0)
I want to filter objects from subscription model like below
subs = subscription.objects.filter(booster = request.user)
Then find creators in the above subs object list and for each creator get the name, numbers Posts, and number of Subscribers. Add this to custom list and pass it to the template to loop over and display the information in the template. Can someone help me how to create this custom list. Thanks!
Ok so here are the basics minus the subscribers because I don't see the relation clearly. This is how to parse the name and the number of posts. \
my_list = []
for sub in subs:
name = sub.creator.name
auth_id = sub.creator.id
posts = Post.objects.filter(author=auth_id)
num_of_posts = len(posts)
my_list.append({
'name':name,
'post_count': num_of_posts,
})
then you would pass mylist thru the template context.
It is a common mistake to name the related_name=… parameter [Django-doc] to the same value as the name of the field. The related_name parameter however is the name of the reverse relation Django will automatically add. So here it means a relation to access for example the related subscription objects of a given CustomUser.
Therefore it makes more sense to rename these, for example like:
class Subscription(models.Model):
creator = models.ForeignKey(
CustomUser,
default=None,
null=True,
on_delete=models.CASCADE,
related_name='created_subscriptions'
)
booster = models.ForeignKey(
CustomUser,
default=None,
null=True,
on_delete=models.CASCADE,
related_name='boosted_subscriptions'
)
sub_value = models.FloatField(blank=True)
sub_id = models.TextField(blank =True)
status = models.BooleanField(default=False)
dateSubscribed = models.DateTimeField(default=timezone.now)
dateSubscriptionEnded = models.DateTimeField(default=timezone.now)
paymentCount = models.FloatField(default=0)
Next we can make a query where:
from django.db.models import Count
CustomUser.objects.filter(
created_subscriptions__booster=request.user
).annotate(
number_of_posts=Count('post', distinct=True)
)
This is a QuerySet of CustomUsers where each CustomUser that arises from this QuerySet has an extra attribute .number_of_posts that contains the number of posts. You thus can iterate over the queryset directly in the template.

Multiple default values specified for column "id" of table in Django 2.1.1

So I keep getting this error saying that there's multiple specified ID values for the device table, but I don't have a clue where I've specified any kind of default ID. I've tried setting a field as primary_key=True but that didn't solve the problem either.
EDIT: Traceback
class Campus(models.Model):
name = models.CharField(max_length=20)
address = models.CharField(max_length=40)
def __str__(self):
return self.name
class Meta:
verbose_name_plural = "Campuses"
class Teacher(models.Model):
name = models.CharField(max_length=20)
phone = models.CharField(max_length=11)
department = models.CharField(max_length=20)
campus = models.OneToOneField(Campus, on_delete=models.CASCADE, default="Not Assigned")
#devices = self.Device.objects.all()
def __str__(self):
return self.name
class Device(models.Model):
inUse = 'IU'
inStock = 'IS'
inMaintenance = 'IM'
damaged = 'DM'
statusChoices = (
(inUse, 'In Use'),
(inStock, 'In Stock'),
(inMaintenance, 'In Maintenance'),
(damaged, 'Damaged'),
)
name = models.CharField(max_length=20)
brand = models.CharField(max_length=20)
status = models.CharField(max_length=2, choices=statusChoices, default=inStock)
#user = models.ForeignKey(Teacher, on_delete=models.CASCADE, default=0)
def __str__(self):
return self.name
After navigating to my PostgreSQL instance I deleted all Django-related data and remade migrations and things are in working order again.
For future users: I recommend deleting your past migrations table in your database.

I am working with Django, During inserting data into database i caught such error

I'm working with django, during inserting data into tables the error is generates as given below...
Error:
int() argument must be a string, a bytes-like object or a number, not 'Tbl_rule_category', How can we solve such error?
view.py
dataToRuleCtgry = Tbl_rule_category(category=category, created_by="XYZ",created_date=datetime.date.today())
dataToRuleCtgry.save()
dataToRule = Tbl_rule(rule_name=rule_name, closure=closure,category_id=Tbl_rule_category.objects.latest('category_id'), created_by="XYZ",created_date=datetime.date.today(), updated_by="XYZ", updated_date=datetime.date.today(), rule_type=rule_type, fk_tbl_rule_tbl_rule_category_id=Tbl_rule_category.objects.latest('category_id'))
dataToRule.save()
models.py
class Tbl_rule_category(models.Model):
category_id = models.AutoField(primary_key=True)
category = models.CharField(max_length=50)
created_by = models.CharField(max_length=50)
created_date = models.DateField(auto_now_add=True)
def __str__(self):
pass # return self.category, self.created_by
class Tbl_rule(models.Model):
rule_id = models.AutoField(primary_key=True)
rule_name = models.CharField(max_length=50)
closure = models.CharField(max_length=50)
category_id = models.IntegerField()
created_by = models.CharField(max_length=50)
created_date = models.DateField(auto_now_add=True)
updated_by = models.CharField(max_length=50)
updated_date = models.DateField(auto_now=True)
rule_type = models.CharField(max_length=50)
fk_tbl_rule_tbl_rule_category_id = models.ForeignKey(Tbl_rule_category,on_delete=models.CASCADE, related_name='fk_tbl_rule_tbl_rule_category_id_r')
def __str__(self):
return self.rule_name, self.closure, self.created_by, self.updated_by, self.rule_type
The error is occurring because the following is trying to add an object into an integer field: category_id=Tbl_rule_category.objects.latest('category_id')
You could just add: category_id=dataToRuleCtgry.get('category_id') or category_id=dataToRuleCtgry.category_id which will solve the error.
You also don't need to add: created_date=datetime.date.today() because your model defines auto_now=true.
As mentioned you should also amend the def __str__(self): to return a string.
https://docs.djangoproject.com/en/2.0/ref/models/instances/#django.db.models.Model.str
Alternatively
You could just add the object link directly to your foreign key for the category model.fk_tbl_rule_tbl_rule_category_id=dataToRuleCtgry. You would no longer need the integer field category_id.
It would be better practice to use the model field name category_id instead of fk_tbl_rule_tbl_rule_category_id. This would mean deleting category_id and then rename fk_tbl_rule_tbl_rule_category_id to category_id.
In Django, the ORM takes care of the basic database details for you; which means in your code you really don't have to worry about individual row ids for maintaining foreign key relationships.
In fact, Django automatically assigns primary keys to all your objects so you should concentrate on fields that are relevant to your application.
You also don't have to worry about naming fields in the database, again Django will take care of that for you - you should create objects that have fields that are meaningful to users (that includes you as a programmer of the system) and not designed for databases.
Each Django model class represents a object in your system. So you should name the classes as you would name the objects. User and not tbl_user. The best practice is to use singular names. Django already knows how to create plural names, so if you create a model class User, django will automatically display Users wherever it makes sense. You can, of course, customize this behavior.
Here is how you should create your models (we will define __str__ later):
class RuleCategory(models.Model):
name = models.CharField(max_length=50)
created_by = models.CharField(max_length=50)
created_date = models.DateField(auto_now_add=True)
class Rule(models.Model):
name = models.CharField(max_length=50)
closure = models.CharField(max_length=50)
created_by = models.CharField(max_length=50)
created_date = models.DateField(auto_now_add=True)
updated_by = models.CharField(max_length=50)
updated_date = models.DateField(auto_now=True)
rule_type = models.CharField(max_length=50)
category = models.ForeignKey(RuleCategory,on_delete=models.CASCADE)
Django will automatically create any primary or foreign key fields, and any intermediary tables required to manage the relationship between the two models.
Now, to add some records:
new_category = RuleCategory(name='My Category', created_by='XYZ')
new_category.save()
# Another way to set values
new_rule = Rule()
new_rule.name = 'Sample Rule'
new_rule.closure = closure
new_rule.created_by = 'XYZ'
new_rule.updated_by = 'XYZ'
new_rule.rule_type = rule_type
new_rule.category = new_category
new_rule.save()
Note this line new_rule.category = new_category - this is how we link two objects. Django knows that the primary key should go in the table and will take care of that automatically.
The final item is customizing the models by creating your own __str__ method - this should return some meaningful string that is meant for humans.
class RuleCategory(models.Model):
name = models.CharField(max_length=50)
created_by = models.CharField(max_length=50)
created_date = models.DateField(auto_now_add=True)
def __str__(self):
return '{}'.format(self.name)
class Rule(models.Model):
name = models.CharField(max_length=50)
closure = models.CharField(max_length=50)
created_by = models.CharField(max_length=50)
created_date = models.DateField(auto_now_add=True)
updated_by = models.CharField(max_length=50)
updated_date = models.DateField(auto_now=True)
rule_type = models.CharField(max_length=50)
category = models.ForeignKey(RuleCategory,on_delete=models.CASCADE)
def __str__(self):
return '{} for category {}'.format(self.name, self.category)
If you notice something, I just put self.category in the __str__ for the Rule model. This is because we have already defined a __str__ for the RuleCategory model, which just returns the category name; so now when we print our Rule we created, we will get Sample Rule for category My Category as a result.

How to add fields together automatically

I'm going to build up an assets management system. Every property has an unique property-code combine with department-code and type-code.
from django.db import models
class Department(models.Model):
# department_code like rm01
department_code = models.CharField(max_length=4, unique=True)
name = models.CharField(max_length=100)
class Type(models.Model):
# type_code like fe03
type_code = models.CharField(max_length=4, unique=True)
name = models.CharField(max_length=100)
class Property(models.Model):
# property_code like rm01fe037767
property_code = models.CharField(max_length=12, unique=True)
name = models.CharField(max_length=100)
department = models.ForeignKey(Department)
type = models.ForeignKey(Type)
How to do that? OR is there another way to achieve the aim?
Yes but not automatically.
In the normal case: when you want to add new Propery ~> User should pick other 2 model right?
dep_id = ?
type_id= ?
p = Property (id = dep_id+type_id, name = "blabla"...)
p.save()
And you should define the PK (default is int field, auto incre ~> to charfield) and input it by yourself
And normally: we don't do that...
We use: ForeignKey like:
class Item(models.Model):
people = models.ForeignKey(People)
name = models.CharField(max_length=40)
value = models.IntegerField(default=0)
def __str__(self):
return self.name