Django rest Ecommerce category and product offers - django

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)

Related

Django rest framework get data from foreign key relation?

I have a models like this:
class Author(models.Model):
name = models.CharField(max_length=150, blank=False, null=False)
dob = models.DateField(null=True, blank=True)
description = models.TextField(max_length=2000, blank=False, default="This author doesn't have any description yet!")
image = models.ImageField()
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
class Meta:
ordering = ['created']
def __str__(self):
return self.name
class Book(models.Model):
title = models.CharField(max_length=200, blank=False, null=False)
author = models.CharField(max_length=200)
genres = models.ManyToManyField(Genre, related_name='genre', blank=True)
author = models.ForeignKey(Author, related_name='author', blank=True, on_delete=models.CASCADE)
description = models.TextField(max_length=1200, blank=False, default="This book doesn't have description yet!")
image = models.ImageField(default="")
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
class Meta:
ordering = ['created']
def __str__(self):
return self.title
class Review(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
book = models.ForeignKey(Book, on_delete=models.CASCADE)
title = models.CharField(max_length=100, null=False, blank=False, help_text="Title overall of your review")
rating = models.IntegerField(validators=[MinValueValidator(0), MaxValueValidator(5)], help_text='Rating in range 0-5')
description = models.TextField(max_length=1000, null=False, blank=False)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
I want to get Book data response in json with my reviews of the book from my Review table but don't know how. I am not getting any useful solution from documentation and Google, please help.
You could set the related_name field in the book field of the Review model.
class Review(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
book = models.ForeignKey(Book, on_delete=models.CASCADE, related_name = 'reviews')
...
Then in the serializer, you can add the related field.
class ReviewSerializer(serializers.ModelSerializer):
class Meta:
model = Review
fields = '__all__'
class BookSerializer(serializers.ModelSerializer):
reviews = ReviewSerializer(many = True)
class Meta:
model = Book
fields = '__all__'
extra_fields = ('reviews', )

IntegrityError at /job/create/ NOT NULL constraint failed: core_job.category_id

I'm creaating an api that user can create a job. when I want to test it with postman and create a job I have this error:
IntegrityError at /job/create/
NOT NULL constraint failed: core_job.category_id
how do i can fix it ?? I'm using generic CreateAPIView
models:
class Category(models.Model):
name = models.CharField(max_length=300)
slug = models.SlugField(max_length=300, unique=True, help_text='write in English.')
sub_category = models.ForeignKey('Category', null=True, blank=True, on_delete=models.CASCADE)
class Job(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
name = models.CharField(max_length=400, unique=True)
slug = models.SlugField(max_length=400, unique=True, allow_unicode=True)
category = models.ForeignKey(Category, on_delete=models.DO_NOTHING)
image_1 = models.ImageField(upload_to='products_pic/%Y/%m/%d/', null=True, blank=True)
description = models.TextField(null=True, blank=True)
phone1 = models.CharField(max_length=12, null=True, blank=True)
phone2 = models.CharField(max_length=12, null=True, blank=True)
phase = models.CharField(max_length=1, null=True, blank=True)
address = models.TextField(null=True, blank=True)
daily_start_work_time = models.TimeField(null=True, blank=True)
daily_end_work_time = models.TimeField(null=True, blank=True)
create_date = models.DateTimeField(auto_now_add=True)
update_date = models.DateTimeField(auto_now=True)
active = models.BooleanField(default=False)
popular = models.BooleanField(default=False)
views:
class JobCreateView(generics.CreateAPIView):
permission_classes = (IsAuthenticated,)
serializer_class = JobSerializer
queryset = Job.objects.all()
serializers:
class CategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = '__all__'
class JobSerializer(serializers.ModelSerializer):
category = serializers.SerializerMethodField()
class Meta:
model = Job
fields = '__all__'
lookup_field = 'slug'
extra_kwargs = {
'url': {'lookup_field': 'slug'}
}
def get_category(self, obj):
return obj.category.name
The category field is not populating with any value when you create the job. I mean category field is Null when you save that form. I am not sure but any way the problem is related to category field

Getting items related to selected foreign key in django

I'm building a django app that has customers model and projects model and tasks model. in tasks model I can select the customer name and project but the problem is that in admin panel it shows all the projects, is there any way to show projects only for the selected customer
from django.db import models
from django.contrib.auth.models import User
from suppliers.models import Currency
from users.models import Profile
class Customer(models.Model):
customer_id = models.AutoField(primary_key=True)
customer_first_name = models.CharField(max_length=200)
customer_last_name = models.CharField(max_length=200)
company = models.CharField(max_length=200)
customer_phone = models.CharField(max_length=200)
customer_address = models.CharField(max_length=200)
email = models.EmailField(null=True, blank=True)
website = models.CharField(max_length=200, null=True, blank=True)
creation_date = models.DateTimeField(auto_now_add=True)
modified_date = models.DateTimeField(auto_now=True)
notes = models.TextField()
def __str__(self):
return str(self.customer_first_name) + ' ' + str(self.customer_last_name)
class Account(models.Model):
max_discount = models.DecimalField(max_digits=2, decimal_places=2)
credit_limit = models.DecimalField(max_digits=20, decimal_places=2)
customer = models.ForeignKey(Customer, on_delete=models.CASCADE, null=True, blank=True)
currency = models.ForeignKey(Currency, on_delete=models.CASCADE)
sales_man = models.OneToOneField(User, on_delete=models.CASCADE)
Agent = models.OneToOneField(Profile, on_delete=models.CASCADE)
status = models.BooleanField(default=True)
reason = models.TextField()
class TaskPriority(models.Model):
priority_id = models.AutoField(primary_key=True)
task_priority_name = models.CharField(max_length=200)
def __str__(self):
return str(self.task_priority_name)
class Project(models.Model):
project_id = models.AutoField(primary_key=True)
project_name = models.CharField(max_length=200)
project_balance = models.DecimalField(max_digits=20, decimal_places=2)
customer_name = models.ForeignKey(Customer, on_delete=models.CASCADE)
creation_date = models.DateTimeField(auto_now_add=True)
modified_date = models.DateTimeField(auto_now=True)
notes = models.TextField()
def __str__(self):
return str(self.project_name)
class Task(models.Model):
task_id = models.AutoField(primary_key=True)
task_name = models.CharField(max_length=200)
customer_name = models.ForeignKey(Customer, on_delete=models.CASCADE, blank=True, null=True)
task_priority = models.ForeignKey(TaskPriority, on_delete=models.CASCADE)
employee = models.ForeignKey(Profile, on_delete=models.CASCADE)
creation_date = models.DateTimeField(auto_now_add=True)
modified_date = models.DateTimeField(auto_now=True)
project = models.ForeignKey(Project, null=True, blank=True, on_delete=models.CASCADE)
file_name = models.FileField(upload_to='projects_files')
notes = models.TextField()
def __str__(self):
return str(self.task_name)
You can use TabularInline to create project tab on customer record view in admin panel.
For example:
class ProjectInline(admin.TabularInline):
model = Project
extra = 1
verbose_name = 'Project'
verbose_name_plural = 'Projects'
list_display = ...
And in Customer Admin model add
class CustomerAdmin(admin.ModelAdmin):
...
inlines = (ProjectInline, )

Django queryset join tables

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.

How to get the minimum value of an instance of django model

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.