How to Retrieve a specific value of a Tuple from Django database - django

So here I have a table named Product which contains Food name,Category,Price,Image,Dataset id column so i would like to retrieve the value of Dataset id only ,in Django
I would like to put parse dataset_id into recommend function but it doesnt give value of 31 while i select Pizza so i tried just printing it and the output in my console is <django.db.models.query_utils.DeferredAttribute object at 0x03B11CE8>
here is my code from views.py
from .models import Product
def cart(request):
if request.user.is_authenticated:
print(Product.dataset_id)
res=recommend(item_id=31, num=3)
customer = request.user.customer
order , created = Order.objects.get_or_create(customer = customer , complete=False)
items = order.orderitem_set.all()
cartItems = order.get_cart_items
print(res)
Here is my code for Products in models.py
class Product(models.Model):
food_id = models.AutoField
food_name = models.CharField(max_length=50, default="")
cateory = models.CharField(max_length=50, default="")
subcategory = models.CharField(max_length=50, default="")
price = models.IntegerField(default=0)
image = models.ImageField(upload_to='menu/images', default="")
dataset_id = models.IntegerField(default = 0)

You need to first get the Product whose dataset_id you want to print.
You can do that by using pk value or any other unique attributes.
i.e : product = Product.objects.get(pk=pk)
print(product.dataset_id)

Related

Relationships in Django - how to filter data

I've looked at a lot of entries and I know how to filter simple relationships. Unfortunately, I'm stuck and I don't know how to filter my table data when one of the tables is a branch of a certain string.
models.py
from django.contrib.auth.models import User
class Autor(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, unique=True)
description = models.TextField(blank=True, null=True)
class Incident(models.Model):
group_no = models.ForeignKey(Group, on_delete=models.CASCADE, default=1)
description = models.TextField(blank=True, null=True)
deleted = models.BooleanField(default=False)
class Department-leader(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="leader")
department = models.ForeignKey(Group, on_delete=models.CASCADE)
class Group(models.Model):
group_no = models.CharField(max_length=40, unique=True)
active = models.BooleanField(default=True)
views.py
def get_author(user):
qs = Autor.objects.filter(user=user)
if qs.exists():
return qs[0]
return None
def show_all(request):
show_all_records = Incident.objects.filter(deleted=False).order_by('-id')[:300]
if request.user.is_authenticated:
autors_list = get_author(request.user)
user_list = get_user_model()
logged_user = get_object_or_404(user_list, username__exact=autors_list)
(...)
print("Logged user: " + str(logged_user.id))
else:
logged_user = ""
context = {
'show_all_records': show_all_records,
'logged_user': logged_user,
}
return render(request, 'incident/all_records.html', context)
The show_all_records variable represents all the records of the Incident table and that is ok.
The second thing I would like to display are entries for the logged in person i.e. all incidents in particular departments of the leader who is logged in.
If the tables were connected linearly, I would have no problem building this filter.
But how to make a filter for this layout of tables?
In pure SQL, it would look something like this:
select
bledy_bledy.nr_zlecenia,
bledy_bledy.ilosc_bledow,
bledy_gruparobocza.nr_grupy,
auth_user.username,
auth_user.id
from
bledy_bledy
LEFT JOIN
bledy_lider_dzial
on
bledy_bledy.nr_grupy_roboczej_id = bledy_lider_dzial.dzial_id
LEFT JOIN
bledy_gruparobocza
on
bledy_lider_dzial.dzial_id = bledy_gruparobocza.id
LEFT JOIN
auth_user
on
bledy_lider_dzial.user_id = auth_user.id
where
auth_user.id = 4
**Can I count on some hint on how to build it?**
I think this may be what you want.
user = request.user
# only need the primary keys of the group leaders for the next query
department_ids = user.leader.all().values_list('department_id', flat=True)
incidents = Incident.objects.filter( group_no_id__in= departments )
Also a suggestion: stick to Django conventions for naming foreign keys and related names. leaders not leader (because it refers to a plurality or set of leaders), and group not group_no because it refers to a Group object. (The actual FK/primary key value is obtained by appending _id to the field name, as used in the above. This is Django "magic".)

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.

how to fetch data from many to many field objects?

I am getting stuck in many to many field objects in my model i want to retrieve the price of product from the order model objects but while fetching it gives sometime many related manager error or query set error
models.py
from django.db import models
from django.contrib import admin
from django.contrib.auth.models import User
class Product(models.Model):
name = models.CharField(max_length=100, db_index=True)
slug = models.SlugField(max_length=100, db_index=True)
description = models.TextField(blank=True)
price = models.DecimalField(max_digits=10, decimal_places=2)
available = models.BooleanField(default=True)
stock = models.PositiveIntegerField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Order(models.Model):
user = models.ForeignKey(User,on_delete= models.SET_NULL,null = True)
product = models.ManyToManyField('Order.Product')
is_ordered = models.BooleanField(default =False)
date_ordered = models.DateTimeField(auto_now = True,null = True)
views.py
def get_product_price(request):
if request.method=="GET":
user=User.objects.get(username = "hemant")
orders = user.order_set.all()
order = orders[0]
price = order.product.price
return HttpResponse(price)
When you are getting value from ManyToManyField, you need to do it like this:
products = order.product.all()
If you want to get the prices, you can do it like this:
products = order.product.all()
for product in products:
print(product.price)
If you want to return prices as a http response, then you can use values_list() to get list of prices from queryset. Like this
import json
views.py
def get_product_price(request):
if request.method=="GET":
user=User.objects.get(username = "hemant")
orders = user.order_set.all()
order = orders[0]
price = list(order.product.all().values_list('price', flat=True))
return HttpResponse(json.dumps(price))

Filtering Django models by user & object

I'm learning Django with a dummy example but having difficulty in understanding how to correctly filter my Django models by an authorised user in my views.
In my view I want to list the transactions associated with a users portfolio. The code below runs but when trying to access the result of 't' I get the error:
'ValueError: The QuerySet value for an exact lookup must be limited to one result using slicing.'
Any help would be much appreciated, thanks.
if request.user.is_authenticated:
# Get model data
pf = Portfolio.objects.filter(user=request.user)
t = Transaction.objects.filter(pf=pf)
My model is as below:
from django.db import models
from django.contrib.auth.models import User
class Portfolio(models.Model):
# Portfolio has one user associated with it
user = models.ForeignKey(User, on_delete=models.CASCADE)
name = models.CharField(max_length=100, default='-')
def __str__(self):
return self.name
class Transaction(models.Model):
# Transaction has one equity associated with it
equity = models.ForeignKey('Equity', on_delete=models.CASCADE, null=True)
# Transaction has one portfolio associated with it
pf = models.ForeignKey('Portfolio', on_delete=models.CASCADE)
BUY = 'BUY'
SELL = 'SELL'
BUY_OR_SELL = (
(BUY, 'BUY'),
(SELL, 'SELL'),
)
action = models.CharField(choices=BUY_OR_SELL, default=BUY, max_length=5)
num = models.FloatField(default=1)
price = models.FloatField(default=0)
date = models.DateField('date')
fee = models.FloatField(default=0)
def __str__(self):
return f'{self.equity}, {self.num}x{self.price}, {self.date:%d %b %Y}'
class Equity(models.Model):
class Meta:
verbose_name_plural = "Equities"
CUR_EUR = 'EUR'
CUR_GBP = 'GBP'
CUR_USD = 'USD'
CURRENCY_CHOICES = (
(CUR_EUR, 'EUR'),
(CUR_GBP, 'GBP'),
(CUR_USD, 'USD'),
)
symbol = models.CharField(max_length=20, default='-')
exchange = models.CharField(max_length=100, default='-')
currency = models.CharField(max_length=15, choices=CURRENCY_CHOICES, default=CUR_USD)
def __str__(self):
return self.symbol
Many thanks!
pf is here a collection of Portfolio objects, so you can query it with the __in lookup [Django-doc]:
Transaction.objects.filter(pf__in=pf)
Or if you are not interested in the Porfolio objects itself, you can make a query like:
Transaction.objects.filter(pf__user=request.user)
The query below will result in a query like:
SELECT transaction.*
FROM transaction
JOIN portfolio ON transaction.pf_id = portfolio.id
WHERE porfolio.user_id = 123
(with 123 the id of the request.user)

View and Template for m2m with Through

In my app i need to store invoices (Invoice) of known products (Product) to calculate points for each seller (User). I'm trying to create form to insert basic invoice data plus inline form with sold products info. To handle it i create model like this:
class Product(models.Model):
group = models.CharField(max_length = 200, blank = False)
mark = models.CharField(max_length = 200, blank = True)
points = models.IntegerField(blank = False)
class Invoice(models.Model):
price = models.FloatField(blank=False)
file = models.FileField(blank=False)
product = models.ManyToManyField(Product, through='Sold')
user = models.ForeignKey(User, on_delete=models.CASCADE)
date = models.DateField()
date_created = models.DateField(auto_now_add=True)
date_updated = models.DateField(auto_now=True)
class Sold(models.Model):
invoice = models.ForeignKey(Invoice, on_delete=models.CASCADE)
product = models.ForeignKey(Product, on_delete=models.CASCADE)
quantity = models.PositiveIntegerField(default=1)
I tried to manage it via django-admin and it work fine with admin.py:
class ProductTabular(admin.TabularInline):
model = Invoice.product.through
class InvoiceAdmin(admin.ModelAdmin):
inlines = [ProductTabular]
exclude = ('product', )
class Meta:
model = Invoice
admin.site.register(Invoice, InvoiceAdmin)
but i'm unable to create such form in own templates. Please, can you help me with views.py and template to get same result as for the django-admin?
I tried via invoce form with inlineformset_factory for the Sold model, but i can't figure out how to save it. Thanks for any help!