Convert SQL query set into Django Model Query-set? - python

I want to convert the following query of SQL into Django Query-set:-
select sum(amount) from accounts_order where status='Pending' and
customer_id=1;
here is my models.py file
from django.db import models
Create your models here.
class Customer(models.Model):
"""All Customers details goes here"""
name = models.CharField(max_length=255, null=False)
email = models.EmailField(null=False)
phone_number = models.CharField(max_length=255, null=False)
date_created = models.DateTimeField(auto_now_add=True)
class Meta:
"""Meta definition for Customer."""
verbose_name = 'Customer'
verbose_name_plural = 'Customers'
def __str__(self):
"""Unicode representation of Customer."""
return self.name
class Order(models.Model):
"""All order details goes here.It has OneToMany relationship with Customer"""
STATUS = (
('Pending', 'Pending'),
('Done', 'Done'),
)
customer = models.ForeignKey(
Customer, null=True, on_delete=models.SET_NULL)
bill_name = models.CharField(max_length=255, null=False)
status = models.CharField(max_length=255, choices=STATUS, null=False)
amount = models.FloatField(max_length=255, null=False)
date_created = models.DateTimeField(auto_now_add=True)
class Meta:
"""Meta definition for Order."""
verbose_name = 'Order'
verbose_name_plural = 'Orders'
def __str__(self):
"""Unicode representation of Order."""
return self.bill_name

You can use a .aggregate(…) [Django-doc] here:
from django.db.models import Sum
Order.objects.filter(
status='Pending', customer_id=1
).aggregate(total_amount=Sum('amount'))['total_amount']

Related

django.db.utils.IntegrityError: FOREIGN KEY constraint failed - Django

First, I know there are a lot of answers regarding this error, but I can't understand why this is erroring out in my case. I am learning Django and any help would be highly appreciated.
I have a Ticket model with ForeignKey reference to Category, Type & GHDUser as below
models.py
`
# from accounts/models.py
class GHDUser(AbstractBaseUser, PermissionsMixin):
emp_id = models.IntegerField(primary_key=True)
email = models.EmailField(_('email address'),unique=True)
username = models.CharField(max_length=150, unique=True)
# from ticket/models.py
class Category(models.Model):
name = models.CharField(max_length=100)
class Meta:
verbose_name = 'Category'
verbose_name_plural = 'Categories'
def __str__(self):
return self.name
class Type(models.Model):
category = models.ForeignKey(Category, on_delete=models.CASCADE)
name = models.CharField(max_length=100)
class Meta:
verbose_name = 'Type'
verbose_name_plural = 'Types'
def __str__(self):
return self.name
class Ticket(models.Model):
status_options = (
('open', 'Open'),
('pending', 'Pending'),
('closed', 'Closed')
)
priority_options = (
('high','High'),
('medium','Medium'),
('low','Low')
)
ticket_no = models.CharField(max_length=10, blank=True)
title = models.CharField(max_length=100)
description = models.TextField(max_length=1000)
category = models.ForeignKey(Category, on_delete=models.PROTECT, default=1)
type = models.ForeignKey(Type, on_delete=models.PROTECT, default=1)
file = models.FileField(upload_to=user_directory_path, blank=True, default='files/Default_Avatar.png')
raised_by_user = models.ForeignKey(GHDUser, on_delete=models.CASCADE, related_name='raised_ticket')
`
Now, I am able to create an instance for Ticket model from Admin Panel, but when I try to do the same via shell / using data from front end, I am getting the below error.
django.db.utils.IntegrityError: FOREIGN KEY constraint failed
Can you please help me understand what I am doing wrong ?

DRF: How can I show all fields of a m2m field instead of just the name

I'm building a simple Lead Generator using Django Rest Framework.
I'm trying to show a list of "assigned facilities" inside a lead using django's many to many fields. But all it will show inside the API is the id of each of the facilities associated to the many to many field. How do I access more than just the name using DRF? I basically need to show the name, a description and a picture of the facility from each facility record.
serializers.py
class LeadUpdateSerializer(serializers.ModelSerializer):
is_owner = serializers.SerializerMethodField()
class Meta:
model = Lead
fields = (
"id",
"first_name",
"last_name",
"PrimaryAddress",
"assigned_facilities",
)
read_only_fields = ("id", "is_owner")
def get_is_owner(self, obj):
user = self.context["request"].user
return obj.agent == user
models.py
class Facility(models.Model):
UUID = models.CharField(max_length=150, null=True, blank=True)
Name = models.CharField(max_length=150, null=True, blank=False)
mainimage = models.ImageField(null=True, blank=True)
FacilityDescription = models.TextField(max_length=1000, null=True, blank=True)
def __str__(self):
return self.Name
class Lead(models.Model):
assigned_facilities = models.ManyToManyField(Facility, related_name='assigned_facilities')
created_at = models.DateTimeField(auto_now_add=True)
first_name = models.CharField(max_length=40, null=True, blank=True)
last_name = models.CharField(max_length=40, null=True, blank=True)
def __str__(self):
return f"{self.first_name} {self.last_name}"
We can like below:
class FacilitySerializer(serializers.ModelSerializer)
class Meta:
fields = (
"id",
"Name",
"mainimage",
"FacilityDescription",
)
class LeadUpdateSerializer(serializers.ModelSerializer):
assigned_facilities = FacilitySerializer(many=True)
is_owner = serializers.SerializerMethodField()
class Meta:
model = Lead
fields = (
"id",
"first_name",
"last_name",
"PrimaryAddress",
"assigned_facilities",
)
read_only_fields = ("id", "is_owner")
def get_is_owner(self, obj):
user = self.context["request"].user
return obj.agent == user

Django Rest Serializer validate gives Invalid pk

I have this situation:
Model Handling
class Handling(models.Model):
STATUS = (
('Active', 'Active'),
('Archived', 'Archived'),
)
entdate = models.DateTimeField(auto_now_add=True, null=True)
extdate = models.DateTimeField(auto_now_add=True, null=True)
kpallet = models.ForeignKey(Pallet, related_name='kpallet', null=True, on_delete= models.PROTECT)
kitem = models.ForeignKey(Item,related_name='kitems', null=True, on_delete= models.PROTECT, limit_choices_to={'kstatus': 'Active'})
quantity = models.SmallIntegerField(null=True)
kstatus = models.CharField(max_length=20, null=True, choices=STATUS)
def __str__(self):
return str(self.kpallet)
Model Item:
class Item(models.Model):
STATUS = (
('Active', 'Active'),
('Disabled', 'Disabled'),
('Archived', 'Archived'),
)
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
name = models.CharField(max_length=50, null=True)
description = models.CharField(max_length=200, null=True)
kdimension = models.ForeignKey(Dimension, null=True, on_delete= models.PROTECT)
kclient = models.ForeignKey(Client, null=True, on_delete= models.PROTECT)
kstatus = models.CharField(max_length=20, null=True, choices=STATUS)
def __str__(self):
return self.name
Serializer:
class HandlingSerializer(serializers.ModelSerializer):
class Meta:
model = Handling
fields = '__all__'
Api:
#api_view(['POST'])
#permission_classes((permissions.AllowAny,))
def handlingCreate(request):
serializer = HandlingSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
else:
print(serializer.errors);
return Response("Error Handling not created")
return Response("Handling Created")
I get this error and i don't understand how to move on:
{'kitem': [ErrorDetail(string='Invalid pk "958c2fd2-bbb6-42d6-8bfe-fbe035e9ceb5" - object does not exist.', code='does_not_exist')]}
I've checked the pk and the object exists so I don't understand where the issue could be.
Thanks for your help in advance.
Fixed thanks to Blackdoor for the input.
This is the correct serializer:
class HandlingSerializer(serializers.ModelSerializer):
kitem = serializers.PrimaryKeyRelatedField(queryset=Item.objects.all(), pk_field=serializers.UUIDField(format='hex_verbose'))
class Meta:
model = Handling
fields = '__all__'
use pk_field=UUIDField for PrimaryKeyRelatedField
class HandlingSerializer(serializers.ModelSerializer):
kitem = serializers.PrimaryKeyRelatedField(queryset=Item.objects.all(), pk_field=UUIDField(format='hex'))
class Meta:
model = Handling
fields = '__all__'

Trying to convert Left Join of SQL into Django query-set?

here is my models.py file
class Customer(models.Model):
"""All Customers details goes here"""
name = models.CharField(max_length=255, null=False)
firm_name = models.CharField(max_length=255, null=False)
email = models.EmailField(null=False)
phone_number = models.CharField(max_length=255, null=False)
location = models.CharField(max_length=255,null=True)
date_created = models.DateTimeField(auto_now_add=True)
class Meta:
"""Meta definition for Customer."""
verbose_name = 'Customer'
verbose_name_plural = 'Customers'
def __str__(self):
"""Unicode representation of Customer."""
return self.name
class Order(models.Model):
"""All order details goes here.It has OneToMany relationship with Customer"""
STATUS = (
('CR', 'CR'),
('DR', 'DR'),
)
customer = models.ForeignKey(Customer, null=True, on_delete=models.SET_NULL)
bill_name = models.CharField(max_length=255, null=False)
payment_date=models.DateField(auto_now=False)
status = models.CharField(max_length=255, choices=STATUS, null=False)
amount = models.FloatField(max_length=255, null=False)
date_created = models.DateTimeField(auto_now_add=True)
description = models.TextField(null=True)
class Meta:
"""Meta definition for Order."""
verbose_name = 'Order'
verbose_name_plural = 'Orders'
def __str__(self):
"""Unicode representation of Order."""
return self.bill_name
i want to access only Customer's name and all fields of Order,in short i want to convert the following SQL in Django Query-set
select name ,bill_name ,status from accounts_customer left join
accounts_order on accounts_customer.id = accounts_order.customer_id
where accounts_order.status="DR";
To attach the customer's name on the order object, you can use annotate with an F expression. https://docs.djangoproject.com/en/3.0/ref/models/expressions/#using-f-with-annotations
orders = Order.objects.annotate(
customer_name=F('customer__name')
).filter(status='DR')
for order in orders:
print(order.customer_name)
If you suspect you will want to access more customer attributes, you may want to select_related (slightly more memory, larger query). What's the difference between select_related and prefetch_related in Django ORM?
orders = Order.objects.select_related('customer').filter(status='DR')
for order in orders:
print(order.customer.name)
You can perform join operation using two ways:
1st: via using select_related
I.e. Order.objects.select_related('customer')
And
2nd: via using filter:
I.e. Order.objects.filter(status__iexact="DR")

No reverse match django class based views

I m new to Django and I am learning it through a project but m stuck with this error which says that NoReverseMatch at /product/create/
here is my models.py file
from django.db import models
from django.conf import settings
from django.core.urlresolvers import reverse
# Create your models here.
class Category(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL,
related_name='category_created')
name = models.CharField(max_length=200, db_index=True)
slug = models.SlugField(max_length=200, db_index=True, unique=True)
class Meta:
ordering = ('name',)
verbose_name = 'category'
verbose_name_plural = 'categories'
def __str__(self):
return self.name
class Product(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL,
related_name='product_created', null= True,blank=True)
category = models.ForeignKey(Category, related_name='products')
name = models.CharField(max_length=200, db_index=True)
slug = models.SlugField(max_length=200, db_index=True)
image = models.ImageField(upload_to='products/%Y/%m/%d', blank=True)
description = models.TextField(blank=True)
price = models.DecimalField(max_digits=10, decimal_places=2)
stock = models.PositiveIntegerField()
available = models.BooleanField(default=True)
negiotiable = models.BooleanField(default=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
users_like = models.ManyToManyField(settings.AUTH_USER_MODEL,
related_name='product_liked',
blank=True)
class Meta:
ordering = ('name',)
index_together = (('id', 'slug'),)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('products_detail',
args=[self.slug])
This is my views.py but I m not sure if there is something wrong with my views
from django.views.generic import *
from django.core.urlresolvers import reverse_lazy
from .models import Category, Product
class CategoryList(ListView):
model = Category
class CategoryDetail(DetailView):
model = Category
class ProductList(ListView):
model = Product
class ProductDetail(DetailView):
model = Product
class ProductCreate(CreateView):
model = Product
fields = ["category", 'name', 'image', 'description', 'price', 'stock','available', 'negiotiable']
class ProductUpdate(UpdateView):
model = Product
fields = ['name', 'image', 'description', 'price', 'stock','available', 'negiotiable']
class ProductDelete(DeleteView):
model = Product
success_url = reverse_lazy('product_list')
I can't tell if this is the problem without the traceback or urls.py but I'm guessing you need to auto-generate the slug field by overriding the save method in the Product model. Instructions here: http://fazle.me/auto-generating-unique-slug-in-django/
Or you could try this:
class Product(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL,
related_name='product_created', null= True,blank=True)
category = models.ForeignKey(Category, related_name='products')
name = models.CharField(max_length=200, unique=True)
slug = models.SlugField(max_length=200, unique=True)
image = models.ImageField(upload_to='products/%Y/%m/%d', blank=True)
description = models.TextField(blank=True)
price = models.DecimalField(max_digits=10, decimal_places=2)
stock = models.PositiveIntegerField()
available = models.BooleanField(default=True)
negiotiable = models.BooleanField(default=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
users_like = models.ManyToManyField(settings.AUTH_USER_MODEL,
related_name='product_liked',
blank=True)
class Meta:
ordering = ('name',)
index_together = (('id', 'slug'),)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('products_detail', args=[self.slug])
def save(self, *args, **kwargs):
self.slug = slugify(self.name)
super(Product, self).save(*args, **kwargs)
Note that this way you will have to change db_index to unique for the name field.

Categories