I am really stuck with merging two tables.
I have tables Item and Transactions
class Item(models.Model):
category_choices = []
item_id = models.AutoField(primary_key=True)
name = models.CharField(max_length=100)
description = models.TextField()
category = models.CharField(max_length=100, choices=category_choices)
image = models.ImageField(upload_to='media')
stock = models.IntegerField()
price = models.DecimalField(max_digits=10, decimal_places=2)
date_added = models.DateTimeField(default=timezone.now())
class Transactions(models.Model):
transaction_id = models.AutoField(primary_key=True)
order_id = models.UUIDField()
item_id = models.ForeignKey(Item, on_delete=models.CASCADE, related_name='transactions')
quantity = models.IntegerField()
price = models.DecimalField(max_digits=10, decimal_places=2)
transaction_date = models.DateTimeField(auto_now_add=True)
username = models.CharField(max_length=100)
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
address_str = models.CharField(max_length=100)
address_plz = models.CharField(max_length=100)
address_place = models.CharField(max_length=100)
address_country = models.CharField(max_length=100, choices=[(name[1], name[1]) for name in countries])
Now I want to render template with transactions and images and items info from Item model. I am trying to use prefetch_related, howeve rit does not work and I do not understand how this should be solved.
def order_history(request):
if request.user.is_authenticated:
transaction = Transactions.objects.order_by('-transaction_date').\
filter(username=request.user).prefetch_related('item')
context = {'orders': transaction}
template_name = 'retail/order_history.html'
return render(request, template_name, context=context)
else:
raise Http404('You are not authorised')
In your transactions table, name your Item column item instead of item_id:
item = models.ForeignKey(Item, on_delete=models.CASCADE, related_name='transactions')
Then your prefetch_related("item") will work as expected.
Related
I'm trying to acheive catgeory and product offers in my project and am unable to come up with a solution. Like if i give offer to a category all products price in category should get the offer and for products its individual.
class Category(models.Model):
category_name = models.CharField(max_length=15, unique=True)
slug = models.SlugField(max_length=100, unique=True)
class Meta:
verbose_name_plural = "Category"
class Products(models.Model):
category = models.ForeignKey(Category, on_delete=models.CASCADE)
product_name = models.CharField(max_length=50, unique=True)
slug = models.SlugField(max_length=100, unique=True)
description = models.TextField(max_length=500)
price = models.IntegerField()
images = models.ImageField(upload_to="photos/products")
images_two = models.ImageField(upload_to="photos/products")
images_three = models.ImageField(upload_to="photos/products")
stock = models.IntegerField()
is_available = models.BooleanField(default=True)
created_date = models.DateTimeField(auto_now_add=True)
modified_date = models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name_plural = "Products"
def __str__(self):
return self.product_name
class CategoryOffer(models.Model):
category = models.OneToOneField(Category, on_delete=models.CASCADE, related_name='cat_offer')
valid_from = models.DateTimeField()
valid_to = models.DateTimeField()
discount = models.IntegerField(
validators=[MinValueValidator(1), MaxValueValidator(100)]
)
is_active = models.BooleanField(default=False)
def __str__(self):
return self.category.category_name
class ProductOffer(models.Model):
product = models.OneToOneField(Products, on_delete=models.CASCADE, related_name='pro_offer')
valid_from = models.DateTimeField()
valid_to = models.DateTimeField()
discount = models.IntegerField(
validators=[MinValueValidator(1), MaxValueValidator(100)]
)
is_active = models.BooleanField(default=False)
def __str__(self):
return self.product.product_name
So above are my models. I don't know how to implement, thought of many ways but it keeps leading to errors.
You are using separate models for Categoryoffer and Productoffer. Make an Offer model with the following field:
class Offer:
name = models.CharField()
valid_from = models.DateTimeField()
valid_to = models.DateTimeField()
discount = models.IntegerField(
validators=[
MinValueValidator(1),
MaxValueValidator(100)
])
is_active = models.BooleanField(default=False)
Now use the foreign key in your category and product models:
class Product:
offer = models.ForeignKey(Offer)
Hi i have a seller model that is related one to one field with user in DJANGO. Seller can create a "deal" and to become seller you first have to create a normal account as a user.
I dont have any idea how to take to the view deals that are from the specyfic seller
MY views.
#user_passes_test(is_seller)
def seller_page(request):
if request.method == "GET":
user = request.user
_seller = Seller.objects.get(user_id=user) # TODO: doesnt work
deals = Deal.objects.get(seller_id=_seller)
form = forms.DealModelForm
context = {'deals': deals, 'form': form}
return render(request, 'seller_page.html', context)
My models
class Seller(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
name = models.CharField(max_length=255)
address = models.CharField(max_length=255)
city = models.CharField(max_length=255)
post_code = models.CharField(max_length=6)
phone = models.CharField(max_length=12)
email = models.CharField(max_length=255)
bank_account = models.CharField(max_length=255)
nip = models.CharField(max_length=255)
is_seller_active = models.BooleanField(default=False)
sells = models.IntegerField(default=0)
class Deal(models.Model):
seller = models.ForeignKey(Seller, on_delete=models.CASCADE)
title = models.CharField(max_length=255)
description = models.TextField()
image = models.ImageField()
is_deal_on = models.BooleanField(default=True)
sell_price = models.DecimalField(default=0, decimal_places=2, max_digits=6, help_text='Cena sprzedaży')
origin_price = models.DecimalField(default=0, decimal_places=2, max_digits=6, help_text='Oryginalna cena',
blank=True, null=True)
time_valid = models.IntegerField(default=12) # ilość miesięcy ile warty jest deal
unique_code = models.CharField(max_length=60, null=True, blank=True)
quantity = models.IntegerField(default=0)
province = models.IntegerField(choices=PROVINCES)
ERROR :
_seller = Seller.objects.get(user_id=user)
If the "user" variable is an integer:
_seller = Seller.objects.get(user__id=user) #Note that is "__" and not "_"
if the "user" variable is an object (User model):
_seller = Seller.objects.get(user=user)
I am trying to get the minimum or the lowest value of a model field in django model. The field is room_Price. I am therefore trying to get the minimum of value of this field for each instance of a model. My model are as as follows
class Hotels(models.Model):
name = models.CharField(max_length=255)
address = models.CharField(max_length=255)
city = models.CharField(max_length=255)
country = models.CharField(max_length=255)
mobile_number = models.CharField(max_length=12)
created_at = models.DateTimeField(default=timezone.now)
last_modified = models.DateTimeField(auto_now=True)
description = models.TextField()
slug = models.SlugField(unique=True)
property_photo = models.ImageField(default='default.jpg', upload_to='hotel_photos')
star_rating = models.PositiveIntegerField()
contact_person = models.ForeignKey(UserProfile, on_delete = models.CASCADE, null=True, blank=True,)
class Room(models.Model):
hotel = models.ForeignKey(Hotels,on_delete = models.CASCADE, null=True, blank=True,)
room_photo = models.ImageField(default='default.jpg', upload_to='room_photos')
room_Name = models.CharField(max_length = 200)
room_details = models.CharField(max_length = 500)
room_Capacity = models.PositiveIntegerField(default = 0)
slug = models.SlugField(unique=True)
# guest_numbers = models.IntegerField(default=0)
room_Price= models.PositiveIntegerField(default = 0)
total_Rooms = models.PositiveIntegerField(default=0)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
user = models.ForeignKey(UserProfile, on_delete=models.CASCADE, null=True, blank=True,)
More details
From the above models, a hotel can have as many rooms as possible. Now i want to fetch the lowest priced room for each hotel. I tried to use Hotels.objects.aggregate(min_price=Min('room__room_Price')) but it is fetching the overall minimum price of all the hotel rooms. Kindly assist
You can try to add ordering to your model and then find lowest price in a loop:
class Room(models.Model):
...
class Meta:
ordering = ['room_Price']
And filter in views:
lowest_prices = {}
for i in Hotels.objects.all():
price = Room.objects.filter(hotel=i.id)[0].room_Price
lowest_prices[i.name] = price
print(lowest_prices)
I put prices in a dict, but you can do anything you want with it.
I have a four models which each contains their own data. The models are:
Category (contains department_id foreign key)
Department (contains data, no foreign key)
ProductCategory (join table containing only product_id and category_id)
Product (contains data with no foreign key)
# models.py (excluded the rest for brevity)
from django.db import models
class Department(models.Model):
department_id = models.AutoField(primary_key=True)
name = models.CharField(max_length=100)
description = models.CharField(max_length=1000, blank=True, null=True)
class Meta:
managed = False
db_table = 'department'
class Category(models.Model):
category_id = models.AutoField(primary_key=True)
#department_id = models.IntegerField()
department = models.ForeignKey(Department, on_delete=models.CASCADE)
name = models.CharField(max_length=100)
description = models.CharField(max_length=1000, blank=True, null=True)
class Meta:
managed = False
db_table = 'category'
class Product(models.Model):
product_id = models.AutoField(primary_key=True)
name = models.CharField(max_length=100)
description = models.CharField(max_length=1000)
price = models.DecimalField(max_digits=10, decimal_places=2)
discounted_price = models.DecimalField(max_digits=10, decimal_places=2)
image = models.CharField(max_length=150, blank=True, null=True)
image_2 = models.CharField(max_length=150, blank=True, null=True)
thumbnail = models.CharField(max_length=150, blank=True, null=True)
display = models.SmallIntegerField()
class Meta:
managed = False
db_table = 'product'
class ProductCategory(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
class Meta:
managed = False
db_table = 'product_category'
unique_together = (('product', 'category'),)
From my endpoint, I need to get all products in a department and return the response in the following format:
"rows": [
{
"product_id": integer,
"name": string,
"description": string,
"price": string,
"discounted_price": string,
"thumbnail": string
}
]
This is the endpoint:
path('products/inDepartment/<int:department_id>/', ProductViewSet.as_view({"get": "get_products_by_department"}))
How can I go about doing this? I'm stuck with the code below:
# products.py
def get_products_by_department(self, request, department_id):
"""
Get a list of Products of Departments
"""
categories = Category.objects.filter(department_id=department_id).values('category_id')
for item in categories:
category_id = item['category_id']
products = ProductCategory.objects.filter(category_id=category_id).values(
'product_id', name=F('product__name'), description=F('product__description'),
price=F('product__price'), discounted_price=F('product__discounted_price'), thumbnail=F('product__thumbnail'))
# Return response
if products.exists():
return Response(products, 200)
else:
return Response(products, 204)
The code above works and gives me the correct response but I'm not sure if I'm doing the query correctly? Should I be using a loop or is there a Django way to do it better without a loop?
Django's ORM allows for reverse relationship lookup.
https://docs.djangoproject.com/en/2.2/topics/db/queries/#lookups-that-span-relationships
categories = Category.objects.filter(department_id=department_id)
products = Product.objects.filter(productcategory__category__in=categories)
--models.py--
class Products(models.Model):
name= models.CharField(max_length=120, unique=True)
slug = models.SlugField(unique=True)
price = models.IntegerField(default=100)
image1 = models.ImageField(upload_to='static/images/home', blank=True, null=True)
class Cart(models.Model):
user = models.ForeignKey(User, null=True, blank=True)
product = models.ManyToManyField(Products, blank=True)
--views.py--
#login_required
def cart(request):
try:
cart_user = Cart.objects.filter(user = request.user)
except:
cart_user = False
if cart_user != False:
j = Products.objects.filter(pk=Cart.objects.filter(user=request.user)) #Not getting results in j
now i want the list of products which is selected by user form Cart Model when he or she is logged in.
how to apply join in two models so that i get all the product list in 'p' variable which is in Cart.product model. Thanks
Shang Wang was right about model naming. Let's use those.
class Product(models.Model):
name= models.CharField(max_length=120, unique=True)
slug = models.SlugField(unique = True)
price = models.IntegerField(default=100)
image1 = models.ImageField(upload_to='static/images/home',blank=True,null=True)
class Cart(models.Model):
user = models.ForeignKey(User,null=True, blank=True)
products = models.ManyToManyField(Product, blank=True)
Now you can use filters like this.
products = Product.objects.filter(cart__user__id=1)
carts = Cart.objects.filter(articles__name__startswith="Something").distinct()