Django _set.all() filter in QuerySet - python

I have database and I want to extract specific data of specific user from queryset. Now i have this
VIEW
def index(request):
customerByName = Customer.objects.get(name='pablo')
shopListById = ShopList.objects.get(transaction_id=1)
shpoListSpecific = customerByName.shoplist_set.all()
specificProducts = shopListById.shoplistproduct_set.all()
context = {'customerByName':customerByName, 'shpoListSpecific':shpoListSpecific, 'shopListById':shopListById,
'specificProducts': specificProducts}
return render(request, 'QuickShopperApp/home.html', context)
MODELS
class Customer(models.Model):
user = models.OneToOneField(User, null=True, blank=True, on_delete=models.CASCADE)
name = models.CharField(max_length=200, null=True, blank=True)
email = models.CharField(max_length=200, null=True, blank=True)
device = models.CharField(max_length=200, null=True, blank=True)
def __str__(self):
if self.name:
name = self.name
else:
name = self.device
return str(name)
class Product(models.Model):
name = models.CharField(max_length=200, null=True)
def __str__(self):
return self.name
class ShopList(models.Model): # cart
customer = models.ForeignKey(Customer, on_delete=models.SET_NULL, null=True, blank=True)
#product = models.ForeignKey(Product, on_delete=models.SET_NULL, null=True)
date_ordered = models.DateTimeField(auto_now_add=True)
complete = models.BooleanField(default=False)
transaction_id = models.CharField(max_length=100, null=True)
def __str__(self):
return str(self.id)
class ShopListProduct(models.Model): # each ShopList will have multiple ShopListProduct
product = models.ForeignKey(Product, on_delete=models.SET_NULL, null=True)
shopList = models.ForeignKey(ShopList, on_delete=models.SET_NULL, null=True) #shoplistitem.shoplist
quantity = models.IntegerField(default=0, null=True, blank=True)
date_added = models.DateTimeField(auto_now_add=True)
def __str__(self):
return str(self.product)
template.html
<h3>specificProducts: {{specificProducts}}</h3>
On my side i see items of specific customer.
specificProducts: <QuerySet [<ShopListProduct: Apple>, <ShopListProduct: Cucumber>, <ShopListProduct: Cucumber>]>
How can i get only Apple, Cucumber, Cucumber?

try this
'specificProducts': specificProducts.values_list('product__name')
or
'specificProducts': list(specificProducts.values_list('product__name', flat=True))
https://docs.djangoproject.com/en/3.1/ref/models/querysets/#values-list

Related

Cannot assign "'Sample Category'": "Product.category" must be a "Category" instance

While creating new products I'm getting such kind of error. Can someone help me?
class Product(models.Model):
user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
name_geo = models.CharField(max_length=200, null=True, blank=True)
image = models.ImageField(null=True, blank=True, default='/placeholder.png')
brand = models.CharField(max_length=200, null=True, blank=True)
category = models.ForeignKey(Category, null=False, default=0, on_delete=models.CASCADE)
price = models.DecimalField(max_digits=7, decimal_places=2, null=True, blank=True)
countInStock = models.IntegerField(null=True, blank=True, default=0)
createdAt = models.DateTimeField(auto_now_add=True)
_id = models.AutoField(primary_key=True, editable=False)
def __str__(self):
return self.name_geo
class Category(models.Model):
_id = models.AutoField(primary_key=True, editable=False)
name = models.CharField(max_length=200, null=True, blank=True)
createdAt = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.name
#api_view(['POST'])
def createProduct(request):
user = request.user
product = Product.objects.create(
user=user,
name_geo="Sample Name",
category="Sample Category",
price=0,
brand='Sample Brand',
countInStock=0,
)
serializer = ProductSerializer(product, many=False)
return Response(serializer.data)
Without separating category class in models.py everything works fine. I mean If i didn't use ForeignKey in Products class for category
It just has to be a Category Instance/Object
product = Product.objects.create(
user=user,
name_geo="Sample Name",
category=Category.objects.get_or_create(name="Sample Category"),
price=0,
brand='Sample Brand',
countInStock=0,
)
Notes:
You could just do a .get() or a .filter().first() if you don't want to create
If you use a form, you can get away with just the Category's PK/_id in the POST
this type of thing: f = form(request.POST) f.is_valid() f.save()
At the end that field will hold the PK/_id/Row# of the Category Obj

How to show FK fields in admin? DJANGO

I'm developing an e-commerce site and I'm trying to show in my ADMIN the 'produto_nome' related in my 'Ordem' table. For now, in my admin, in the 'Ordem' table, it's just showing the id of each object. Is it possible to show field 'produto_nome' in that 'Ordem' table ?
Below is my models
class Categoria(models.Model):
nome = models.CharField(max_length=50)
def __str__(self):
return self.nome
class Produto(models.Model):
produto_nome = models.CharField(max_length=70)
preco = models.IntegerField()
quantidade_em_estoque = models.IntegerField()
quantidade_vendida = models.IntegerField()
categoria = models.ForeignKey(Categoria, on_delete=models.CASCADE)
descricao = models.TextField(default='', blank=True, null=True)
slug = models.SlugField(unique=True)
image = models.ImageField(upload_to="products/%Y/%m/%d", blank=True, null=True)
def __str__(self):
return self.produto_nome
def get_absolute_url(self):
return reverse('produto:produto_detail', kwargs={'slug': self.slug})
class Ordem(models.Model):
user = models.ForeignKey(CustomUser, on_delete=models.SET_NULL, blank=True, null=True)
data_pedido = models.DateTimeField(auto_now_add=True, null=True, blank=True)
enviado = models.BooleanField(default=False, null=True, blank=True)
transaction_id = models.CharField(max_length=200, null=True)
def __str__(self):
return str(self.id)
def get_total_preco(self):
total = 0
for pedido in self.produtos_itens.all():
total += pedido.get_total_item_preco()
return total
class OrdemItem(models.Model):
produto = models.ForeignKey(Produto, on_delete=models.SET_NULL, blank=True, null=True)
ordem = models.ForeignKey(Ordem, on_delete=models.SET_NULL, blank=True, null=True)
quantidade = models.IntegerField(default=0, null=True, blank=True)
data_add = models.DateTimeField(auto_now_add=True, null=True, blank=True)
def __str__(self):
return f'{self.quantidade} unidade de {self.produto.produto_nome}'
def get_total_item_preco(self):
return self.quantidade * self.produto.preco
I added a method in my models 'Ordem' to return the 'produto_nome'. And then I called in my admin
models.py
class Ordem(models.Model):
user = models.ForeignKey(CustomUser, on_delete=models.SET_NULL, blank=True, null=True)
data_pedido = models.DateTimeField(auto_now_add=True, null=True, blank=True)
enviado = models.BooleanField(default=False, null=True, blank=True)
transaction_id = models.CharField(max_length=200, null=True)
def __str__(self):
return str(self.id)
def produtos(self):
return list(OrdemItem.objects.filter(ordem__id=self.id))
def get_total_preco(self):
total = 0
for pedido in self.produtos_itens.all():
total += pedido.get_total_item_preco()
return total
admin.py
class OrdemAdmin(admin.ModelAdmin):
list_display= ('id', 'enviado', 'produtos')
admin.site.register(Categoria)
admin.site.register(Produto, ProdutoAdmin)
admin.site.register(OrdemItem)
admin.site.register(Ordem, OrdemAdmin)

How to access other model fields through foreign key in Django Views

I want to query from OrderItem Model like
total_orders = OrderItem.objects.filter(product.user == request.user.id).count()
but i am getting error
**
NameError at /home
name 'product' is not defined
**
MY MODELS:
Product Model:
class Product(models.Model):
title = models.CharField(max_length=150)
user = models.ForeignKey(
User, blank=True, null=True, on_delete=models.SET_DEFAULT, default=None)
description = models.TextField()
price = models.FloatField()
quantity = models.IntegerField(default=False, null=True, blank=False)
minorder = models.CharField(
max_length=150, help_text='Minum Products that want to sell on per order', null=True, default=None, blank=True)
image = models.ImageField()
category = models.ForeignKey(
Categories, default=1, on_delete=models.CASCADE)
slug = models.SlugField(blank=True, unique=True)
def __str__(self):
return self.title
Order Item Model
class OrderItem(models.Model):
product = models.ForeignKey(
Product, on_delete=models.SET_NULL, blank=True, null=True)
order = models.ForeignKey(
Order, on_delete=models.SET_NULL, blank=True, null=True)
quantity = models.FloatField(default=0, null=True, blank=True)
date_orderd = models.DateTimeField(auto_now_add=True)
user = models.ForeignKey(
User, on_delete=models.SET_NULL, blank=True, null=True)
price = models.FloatField(blank=True, null=True)
def __str__(self):
return str(self.product)
My View:
def home(request):
total_orders = OrderItem.objects.filter(
product.user == request.user.id).count()
return render(request, "sellerprofile/home.html", {'total_orders': total_orders})
Do:
total_orders = OrderItem.objects.filter(product__user=request.user).count()
You can look at the documentation here about field lookups on more detail.

How to autocomplete input in field Django

I have a product model. I need to autocomplete product name into input field. How can I code?
class Product(models.Model):
product_name = models.CharField(max_length=255)
product_detail = models.TextField(blank=True, null=True)
product_price = models.FloatField(blank=True)
category = models.CharField(max_length=30)
product_image = models.ImageField(upload_to='pictures/%Y/%m/%d/', max_length=255, blank=True, null=True)
product_amount = models.IntegerField(blank=True, null=True)
del_flag = models.BooleanField(default=False)
def __str__(self):
return self.product_name

Django: get the max count of a foreign key based on other foreign key

I have this Model:
class Complaint(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, default=1)
date_created = models.DateTimeField(auto_now_add=True, null=True, blank=True)
name = models.CharField(max_length=255, unique=True)
definition = models.TextField(blank=False, default="")
is_violent = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
def __str__(self):
return self.name
class Meta:
ordering = ['name']
def get_absolute_url(self):
return reverse('complaint-details', kwargs={'pk': self.pk})
class Service(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, default=1)
date_created = models.DateTimeField(auto_now_add=True, null=True, blank=True)
name = models.CharField(max_length=255, unique=True)
definition = models.TextField(blank=True, default="")
is_active = models.BooleanField(default=True)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('service-details', kwargs={'pk': self.pk})
class Location(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, default=1)
date_created = models.DateTimeField(auto_now_add=True, null=True, blank=True)
location_name = models.CharField(max_length=255, unique=True)
loc_lat = models.DecimalField(max_digits=9, decimal_places=6)
loc_long = models.DecimalField(max_digits=9, decimal_places=6)
pop = models.PositiveIntegerField(default=500)
is_AOR = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
def __str__(self):
return self.location_name
class Blotter(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, default=1)
date_created = models.DateTimeField(auto_now_add=True, null=True, blank=True)#default=timezone.now().date()
date = models.DateField(blank=True)
time = models.TimeField(blank=True)
entry_number = models.CharField(max_length=255, unique=True,validators=[RegexValidator(r'^\d{1,255}$')])
complaints = models.ForeignKey(Complaint, on_delete=models.CASCADE, null=True, blank=True)
service = models.ForeignKey(Service, on_delete=models.CASCADE, null=True, blank=True)
information = models.TextField(blank=False, default="")
location = models.ForeignKey(Location, on_delete=models.CASCADE, null=True, blank=True)
is_active = models.BooleanField(default=True)
class Meta:
ordering = ("date_created",)
def __str__(self):
return (self.entry_number)
def get_absolute_url(self):
return reverse('details-blotter', kwargs={'pk': self.pk})
And I have this serializer:
class APILocationListSerializer(serializers.Serializer):
address = serializers.CharField()
latitude = serializers.DecimalField(max_digits=9, decimal_places=5)
longitude = serializers.DecimalField(max_digits=9, decimal_places=5)
population= serializers.IntegerField()
crime_count=serializers.IntegerField()
crime_rate=serializers.DecimalField(max_digits=4, decimal_places=3)
is_aor = serializers.BooleanField()
class Meta:
model = Blotter
fields= [
'address',
'latitude',
'longitude',
'population',
'crime_count',
'crime_rate'
'is_aor',
]
def to_representation(self, value):
context = {
value['address']:
{
'coordinates':[value['latitude'],value['longitude']],
'Population': value['population'],
'Crime-Count': value['crime_count'],
'Crime-Rate': value['crime_rate'],
'Area-Of-Responsibility': value['is_aor'],
}
}
return context
And ListApiView:
class APILocationList(generics.ListAPIView):
serializer_class = APILocationListSerializer
def get_queryset(self):
q=Blotter.objects.values('location__location_name').annotate(
address=F('location__location_name'),
latitude=F('location__loc_lat'),
longitude=F('location__loc_long'),
population=F('location__pop'),
crime_count=Count('complaints', filter=Q(complaints__is_active=True) and Q(complaints__isnull=False)),
crime_rate=(Cast(F('crime_count'), FloatField())/Cast(F('population'), FloatField()))*100000,
is_aor=F('location__is_AOR')
)
q1 = q.filter(location__is_AOR=True).order_by('address')
query_search = self.request.GET.get("q")
if query_search:
q1 = q.filter(Q(location__is_AOR=True) and Q(location__location_name__icontains=query_search)).order_by('address')
return q1
I'm new to django and DRF. I want to achieve a result like this in my API Not Achieved
but this is the result that i've achieved so far Achieved
As you can see in the picture, I want to count the crime trend (highest count of a crime and the crime itself) in every location.
My questions are:
Is this even achievable/possible to get these results using just one query?
If yes, how?
If no, is there any other way to achieve these kind of results?
Thank you in advance!

Categories