django Rest-framework serialize two tables - python

i have table "Books" with some fields, and i have table "Prices", each customer have self price, i don't know how get price for definitely client, how i must configure serializer? please, help me,
for example:
Book1 have 2 prices: Price1 - 100$, Price2 - 150$
Customer1 must buy with just Price1,
Customer2 must buy with just Price2
i need get for first Customer json like:
[{"code":"УТ-11111","author":"Пушкин","title":"Книга 1","price":"100"}]
for Second Customer
[{"code":"УТ-11111","author":"Пушкин","title":"Книга 1","price":"150"}]
.
class Book(models.Model):
title = models.CharField('Заголовок', max_length=250)
code = models.CharField('Код', primary_key=True, max_length=10)
isbn = models.CharField('ISBN', max_length=18, null=True, blank=True)
ean13 = models.CharField('EAN-13', max_length=13, null=True, blank=True)
author = models.ForeignKey(Author, on_delete=models.SET_NULL, null=True, blank=True, verbose_name='Автор')
class PricesName(models.Model):
name = models.CharField('Вид цены', max_length=20)
def __str__(self):
return self.name
class Price(models.Model):
book = models.ForeignKey(Book, on_delete=models.CASCADE)
PricesName = models.ForeignKey(PricesName, on_delete=models.CASCADE)
price = models.FloatField()
def __str__(self):
return self.book.title+" "+self.PricesName.name
######### Serializers.py ##########################
class BookSerializer(serializers.ModelSerializer):
author = serializers.StringRelatedField()
class Meta:
model = Book
fields = #'__all__'
#### API.py ####
class BookViewSet(viewsets.ModelViewSet):
queryset = Book.objects.all()
permission_classes = [
permissions.AllowAny
]
serializer_class = BookSerializer
filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter)
filter_fields = ('title', 'author')
search_fields = ('title', 'author')
pagination_class = StandardResultsSetPagination

problem is solved
class BookSerializer(serializers.ModelSerializer):
prices = serializers.SerializerMethodField()
def get_prices(self, serializer):
#PriceName__id - price number allowed to current Customer
book_price = Price.objects.filter(book=serializer.code, PricesName__id=2).first()
try:
price = getattr(book_price, "price")
except:
price = 0
return price
class Meta:
model = Book
fields = "__all__"

Related

Calculate the total amount of the cart in django rest framework

I'm new in django,I need calculate cart summa and I have these models:
class Customer(Base):
name = models.CharField(max_length=100)
phone_number = models.CharField(max_length=100, blank=True, null=True)
comments = models.CharField(max_length=255, blank=True, null=True)
class Cart(Base):
user = models.ForeignKey(Customer, on_delete=models.CASCADE, related_name="cart")
cart_number = models.CharField(max_length=500, default=increment_cart_number, null=True, blank=True)
total_summa = models.FloatField()
is_saved = models.BooleanField(default=False)
class Item(Base):
cart = models.ForeignKey(Cart, on_delete=models.CASCADE, related_name='items')
product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='product')
product_price = models.FloatField()
quantity = models.IntegerField(default=1)
I used generics view, Can i calculate cart summa like this
Bread 3x6000 = 18000
Milk 2x500 = 10000
Total_Summa = 28000
serializers.py
class CartCreateSerializer(serializers.ModelSerializer):
class Meta:
model = Cart
fields = [ 'id', 'user', 'cart_number', 'create_date', 'total_summa', 'time', 'is_saved', ]
Could you help me please?
You can try the following using Sum and F expression
from django.db.models import F, Sum
cart.total_summa = Item.objects.filter(cart=cart).annotate(per_item_price=F('product_price')*F('quantity')).annotate(total_summa=Sum('per_item_price'))
Inside serializers you can use the following way
class CartCreateSerializer(serializers.ModelSerializer):
total_summa = serializers.SerializerMethodField("get_total_summa", read_only=True)
class Meta:
model = Cart
fields = [ 'id', 'user', 'cart_number', 'create_date', 'total_summa', 'time', 'is_saved']
def get_total_summa(self, obj):
return obj.items.annotate(per_item_price=F('product_price')*F('quantity')).annotate(total_summa=Sum('per_item_price')).values('total_summa')

DRF display nested JSON

I have my DRF app. In my case, one wallet can have many entries such as income or expense. When I call my endpoint (viewset) I get data in this format:
[
{
"id": "d458196e-49f1-42db-8bc2-ee1dba438953",
"owner": 1,
"viewable": [],
"entry": []
}
]
How can I get the content of "entry" variable?.
class Category(models.Model):
name = models.CharField(max_length=20, unique=True)
def __str__(self):
return self.name
class BudgetEntry(models.Model):
STATE= [
('income','income'),
('expenses','expenses'),
]
amount = models.IntegerField()
entry_type = models.CharField(max_length=15, choices=STATE, null=True)
entry_category = models.ForeignKey(Category, null=True, blank=True, on_delete=models.SET_NULL)
class WalletInstance(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, unique=True)
owner = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='owner', on_delete=models.CASCADE)
viewable = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='can_view', blank=True)
entry = models.ManyToManyField(BudgetEntry, related_name='BudgetEntry', blank=True)
Serializers.py:
class BudgetEntrySerializer(serializers.ModelSerializer):
class Meta:
model = BudgetEntry
fields = '__all__'
class WalletInstanceSerializer(serializers.ModelSerializer):
owner = serializers.ReadOnlyField(source='owner.id')
class Meta:
model = WalletInstance
fields = '__all__'
Views.py:
class WalletViewset(viewsets.ModelViewSet):
permission_classes = [IsAuthenticated]
serializer_class = WalletInstanceSerializer
def get_queryset(self):
user_id = self.request.user.id
available = WalletInstance.objects.filter(
Q(owner=user_id)
)
return available
Change your serializer like this:
class WalletInstanceSerializer(serializers.ModelSerializer):
owner = serializers.ReadOnlyField(source='owner.id')
entry = BudgetEntrySerializer(many=True, read_only=True)
class Meta:
model = WalletInstance
fields = '__all__'

How can I filter the field so that when I select a category, only those products that belong to this category are displayed?

My models, category and product. Each product has a category field, which is linked through ForeignKey.
class Category(models.Model):
name = models.CharField(max_length=50, unique=True)
description = models.TextField()
image = models.ImageField(upload_to='category', blank=True)
class Meta:
verbose_name = 'category'
verbose_name_plural = 'categories'
def __str__(self):
return self.name
class Product(models.Model):
name = models.CharField(max_length=50, unique=True)
description = models.TextField()
category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name='category')
price = models.DecimalField(max_digits=10, decimal_places=2)
image = models.ImageField(upload_to='product', blank=True)
stock = models.PositiveIntegerField()
available = models.BooleanField(default=True)
created = models.DateTimeField(auto_now_add=True)
update = models.DateTimeField(auto_now=True)
class Meta:
verbose_name = 'product'
verbose_name_plural = 'products'
def __str__(self):
return self.name
And views, a product category can be selected and when I click on a category, I want the product to appear only in that category
class CategoriesList(LoginRequiredMixin, ListView):
login_url = 'login/'
template_name = 'index.html'
model = Category
class ProductsList(ListView):
template_name = 'products.html'
model = Product
def get_queryset(self):
return super().get_queryset().filter(category=category_id)

How to fetch data from other table django rest framework

I have a cartmodel, cartitem and offlinecheckout model. I want to display cartitem instead of cartmodel id, I want to display all the cartitem data which have cart_id = offlinecheckout cart_id. But I got this response.
I tried a lot but didn't get. Anybody will please help me.
views.py
class GetAPI(APIView):
def get(self, request, *args, **kwargs):
serializer = OfflineSerializer()
return Response(serializer.data)
models.py
class OfflineCheckOut(models.Model):
billing_name = models.CharField(max_length=254)
billing_phone_no = models.CharField(max_length=15)
user = models.ForeignKey('accounts.User', on_delete=models.CASCADE)
cart = models.ForeignKey('cart.CartModel', on_delete=models.CASCADE)
cartitem = models.ManyToManyField(CartItem, blank=True)
# time_slot = models.ForeignKey('category.TimeSlot', on_delete=models.CASCADE)
address = models.ForeignKey('cart.CustomerAddress', on_delete=models.CASCADE)
status_choice = [
('0', 'Offline'),
('1', 'Online')
]
status = models.CharField(max_length=3, choices=status_choice, default=0)
# date = models.DateField()
date = models.DateField()
time_slot = models.ForeignKey('category.TimeSlot', on_delete=models.SET_NULL, null=True, blank=True)
order_id = models.CharField(max_length=254, blank=True)
# date = models.DateField()
razorpay_payment_id =models.CharField(max_length=254, blank=True)
razorpay_signature = models.CharField(max_length=254, blank=True)
paid = models.BooleanField(default=False)
service = models.ForeignKey('service.ServiceProvider', on_delete=models.SET_NULL, null=True, blank=True)
class CartModel(models.Model):
user = models.ForeignKey('accounts.User', on_delete=models.CASCADE)
status_choice = [
('1', 'open'),
('2', 'closed')
]
status = models.CharField(max_length=2, choices=status_choice, default=1)
validated = models.BooleanField(default=False)
def __str__(self):
return self.user.username
#property
def total_price(self):
return self.cartitem_set.aggregate(
total_price=Sum(F('quantity') * F('price'))
)['total_price'] or Decimal('0')
class CartItem(models.Model):
cart = models.ForeignKey('CartModel', on_delete=models.CASCADE)
user = models.ForeignKey('accounts.User', on_delete=models.CASCADE)
service = models.ForeignKey('accounts.SubCategory', on_delete=models.CASCADE)
defects = models.ForeignKey('category.Defects', on_delete=models.CASCADE)
quantity = models.IntegerField(default=1)
price = models.IntegerField()
created_on = models.DateTimeField(auto_now_add=True)
updated_on = models.DateTimeField(auto_now_add=True)
order_placed = models.BooleanField(default=False)
serializers.py
class OfflineSerializer(serializers.ModelSerializer):
def total(self, obj):
return obj.total
total = serializers.IntegerField(read_only=True)
cartitems = CartItemSerializer( read_only=True, many=True)
class Meta:
model = OfflineCheckOut
fields = ['user', 'billing_name','billing_phone_no','cartitem', 'cartitems','cart', 'date', 'time_slot', 'address', 'total']
extra_fields = ['total', 'cartitems']
You have to put them in a serializer for CartModel. Then OfflineSerializer will use that for cart field.
class CartModelSerializer(serializers.ModelSerializer):
cartitem_set = CartItemSerializer(read_only=True, many=True)
class Meta:
model = CartModel
fields = [
"cartitems_set",
# other fields here
]
class OfflineSerializer(serializers.ModelSerializer):
def total(self, obj):
return obj.total
total = serializers.IntegerField(read_only=True)
cart = CartModelSerializer(read_only=True)
class Meta:
model = OfflineCheckOut
fields = ['user', 'billing_name','billing_phone_no','cartitem', 'cartitems','cart', 'date', 'time_slot', 'address', 'total']
extra_fields = ['total', 'cartitems']
EDIT: Changed the related name serializer from cartlineitems_set to cartlineitem_set

Retrieve query from django ORM

I created a Company in my django app, two or more person can login with the same company. I want to show the data of one user of the company to the other user of the company.
To simplify: If user1 of a company creates an object, then it should be visible to all the users of that company
Models.py
class User(AbstractUser):
is_employee = models.BooleanField(default=False)
is_client = models.BooleanField(default=False)
class Company(models.Model):
company_name = models.CharField(max_length=255, default=0)
company_email = models.EmailField(max_length=255, default=0)
company_phone = models.CharField(max_length=255, default=0)
def __str__ (self):
return self.company_name
class Employee(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
company = models.ForeignKey(Company, on_delete=models.CASCADE, related_name='comapany_owner')
def __str__ (self):
return self.user.username
class Product(models.Model):
product_name = models.CharField(max_length=255, default=0)
product_priceperunit = models.IntegerField(default=0)
product_owner = models.ForeignKey(Employee, on_delete=models.CASCADE, related_name='product_owner')
Views.py
#method_decorator([login_required, employee_required], name='dispatch')
class ProductsTableView(ListView):
model = Product
context_object_name = 'product'
template_name = 'packsapp/employee/employeeProductsTable.html'
def get_queryset (self):
queryset = Product.objects.filter(product_owner=self.request.user.employee)
return queryset
Here I am extracting the data by employee. How can I modify the query to give the data of all the employee of the same company ??
If that means that the product_owner of that Product belongs to the same company as the compnay of that employee, we can filter with:
#method_decorator([login_required, employee_required], name='dispatch')
class ProductsTableView(ListView):
# ...
def get_queryset (self):
return Product.objects.filter(
product_owner__company=self.request.user.employee.company
)

Categories