I'm filtering for stores. And I need to sort the stores by rating but the rating is considered by a complex form, I can sort them by one field but how to count for each I do not know
that is current version order by rate
shops = shops.order_by('rate')
But you need to put the formula instead of the field rate, how is this done?
class Shop(models.Model):
name = models.CharField(max_length=255, verbose_name=u'Название')
time_begin = models.TimeField(max_length=255,
verbose_name=u'Время начала работы')
time_end = models.TimeField(max_length=255,
verbose_name=u'Время окончания работы')
phone = models.CharField(max_length=255, verbose_name=u'Телефон')
preview = models.FileField(upload_to='files/shop/preview')
delivery_price = models.IntegerField(verbose_name=u'Стоимость доставки')
min_price = models.IntegerField(verbose_name=u'Мин доставка', null=True)
min_order = models.IntegerField(verbose_name=u'Минимальный заказ')
del_wait_time = models.IntegerField(verbose_name=u'Время доставки минут')
is_always = models.BooleanField(verbose_name=u'Круглосуточно?',
default=True, blank=True)
is_cash = models.BooleanField(verbose_name=u'Наличными',
default=True, blank=True)
is_card = models.BooleanField(verbose_name=u'Картой курьеру',
default=True, blank=True)
is_online = models.BooleanField(verbose_name=u'Онлайн-оплата',
default=True, blank=True)
is_points = models.BooleanField(verbose_name=u'Еда за баллы',
default=True, blank=True)
is_sale = models.BooleanField(verbose_name=u'Акция',
default=True, blank=True)
is_new = models.BooleanField(verbose_name=u'Новый магазин',
default=True, blank=True)
notification = models.CharField(max_length=255,
verbose_name=u'Важное уведомление',
blank=True, null=True)
email = models.CharField(max_length=255, verbose_name=u'E-mail')
review_email = models.CharField(max_length=255,
verbose_name=u'Review E-mail',
default='null')
rate = models.FloatField(max_length=255, verbose_name=u'Рейтинг')
destination = models.CharField(max_length=255,
verbose_name=u'Местоположение')
specific = models.CharField(max_length=255, default='',
verbose_name=u'Специализация ресторана')
description = models.TextField(max_length=3000,
verbose_name=u'Описание')
cook = models.CharField(max_length=255, verbose_name=u'Имя повара',
blank=True, null=True)
image_cook = models.FileField(upload_to='files/shop/cook',
blank=True, null=True)
desc_cook = models.TextField(max_length=3000,
verbose_name=u'Описание повара',
blank=True, null=True)
shoptype = models.ForeignKey(ShopType, verbose_name=u'Тип заведения',
related_name="shop")
slider = models.ManyToManyField(Slider, verbose_name=u'Слайдер',
related_name="slider",
blank=True)
kitchen = models.ManyToManyField(Kitchen)
Lacking a more detailed statement of the problem, I will give a vague answer. (to be filled in if more details show up)
You could do this by annotating the queryset with a calculated value. See the documentation here
What this means is that you're going to ask the database to figure out the "rate", for example by dividing each shop's distance by its time, and add that value to the data returned for each shop. You could then do an order_by based on that field.
Related
I can't find the answer to the following question about learning application building:
I have task model, which has one-to-many relations with other models: text_message, image_message, video_message, quiz_message, web_page_message (let's call them blocks) and I want to allow the user to choose the order in which these blocks will be sent.
The issue is that if I just add small integer field called 'order' in these blocks' classes - user still can choose a number that would be much bigger than the overall number of existing blocks.
So what is the best way to make such ordering?
Thank you for your answers.
UPD.:
Sorry if the code is not perfect, it is my first real Django project.
Added my models.
Questions:
How to make an order through all these messages?
How to design models in such a way to give the ability to the user to change this ordering?
class task(models.Model):
employees_appointed_id = models.ManyToManyField(profile, related_name='task_to_appointed_users')
employees_finished_id = models.ManyToManyField(profile, related_name='task_to_users_finished', blank=True, null=True)
creator_user_id = models.ForeignKey('profile', on_delete=models.CASCADE, related_name='who_created_task')
description = models.TextField(max_length=1000)
created_datetime = models.DateTimeField(models.DateTimeField(auto_now=True))
deadline = models.DateTimeField(blank=True, null=True)
title = models.CharField(max_length=55)
course = models.ForeignKey('course', on_delete=models.CASCADE)
mentor = models.ManyToManyField(profile, blank=True, null=True, related_name='task_to_profile')
class text_message(models.Model):
text = models.CharField(max_length=3900)
number_by_order = models.IntegerField()
task = models.ForeignKey('task', on_delete=models.CASCADE, related_name='message_to_task')
creator_user_id = models.ForeignKey('profile', on_delete=models.CASCADE, related_name='message_to_creator_user')
course_id = models.ForeignKey('course', on_delete=models.CASCADE, related_name='messages_to_course')
created_datetime = models.DateTimeField(auto_now=True)
class video_message(models.Model):
description = models.CharField(max_length=1024)
media = models.ForeignKey('media', on_delete=models.CASCADE)
task = models.ForeignKey('task', on_delete=models.CASCADE, related_name='video_message_to_task')
class web_page_message(models.Model):
link = models.CharField(max_length=255)
description = models.TextField(max_length=2000, blank=True, null=True)
task = models.ForeignKey('task', on_delete=models.CASCADE, related_name='web_page_to_task')
class image_message(models.Model):
media = models.ForeignKey('media', on_delete=models.CASCADE)
description = models.TextField(max_length=1024)
task = models.ForeignKey('task', on_delete=models.CASCADE, related_name='image_message_to_task')
class quiz_message(models.Model):
question = models.CharField(max_length=300)
option_1 = models.CharField(max_length=100)
option_2 = models.CharField(max_length=100)
option_3 = models.CharField(max_length=100, blank=True, null=True)
option_4 = models.CharField(max_length=100, blank=True, null=True)
option_5 = models.CharField(max_length=100, blank=True, null=True)
option_6 = models.CharField(max_length=100, blank=True, null=True)
option_7 = models.CharField(max_length=100, blank=True, null=True)
option_8 = models.CharField(max_length=100, blank=True, null=True)
option_9 = models.CharField(max_length=100, blank=True, null=True)
option_10 = models.CharField(max_length=100, blank=True, null=True)
explanation = models.CharField(max_length=200, blank=True, null=True)
task = models.ForeignKey('task', on_delete=models.CASCADE, related_name='quiz_message_to_task')
I'm working on a Django Ecommerce project where product has several attributes like. size, color( A single product can have multiple attributes with different size and color). No i'm trying to filter products using django_filters but unable to filter by its attributes.
Product Model:
class Product(models.Model):
variations = (
('None', 'None'),
('Size', 'Size'),
)
name = models.CharField(max_length=200, unique=True)
store = models.ManyToManyField(Store)
slug = models.SlugField(null=True, blank=True, unique=True, max_length=500)
sku = models.CharField(max_length=30, null=True)
tax = models.IntegerField(null=True, blank=True)
stock = models.CharField(max_length=10, null=True)
variations = models.CharField(choices=variations, max_length=20)
short_description = models.CharField(max_length=500, null=True)
details = RichTextUploadingField(null=True, blank=True)
price = models.DecimalField(max_digits=10, decimal_places=2)
discounted_price = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True)
image = models.ImageField(upload_to='product/images', default='product.png', null=True,
blank=True)
image_one = models.ImageField(upload_to='product/images', null=True, blank=True)
image_two = models.ImageField(upload_to='product/images', null=True, blank=True)
image_three = models.ImageField(upload_to='product/images', null=True, blank=True)
image_four = models.ImageField(upload_to='product/images', null=True, blank=True)
image_five = models.ImageField(upload_to='product/images', null=True, blank=True)
tags = models.ManyToManyField(Tags)
category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True, blank=True,
related_name='products')
status = models.CharField(max_length=20, choices=(('Active', 'Active'), ('Inactive',
'Inactive')))
brand = models.ForeignKey(Brand, on_delete=models.PROTECT, blank=True, null=True)
offer = models.ForeignKey(Offer, on_delete=models.CASCADE, null=True,
blank=True) # This is used only for filtration
Product attribute model
class ProductAttribute(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE)
size = models.ForeignKey(Size, on_delete=models.CASCADE, null=True, blank=True)
price = models.DecimalField(max_digits=10, decimal_places=2, validators=
[MinValueValidator(1)])
discounted_price = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True)
stock = models.CharField(max_length=10, null=True)
The standard approach would be to define the attributes in the "Product" model. However, if you insist on doing this, the code will be:
filtered_ProductAttributes=ProductAttribute.objects.filter(size="12")
products=[filtered_ProductAttribute.product for filtered_ProductAttribute in filtered_ProductAttributes]
As you can see the code seems very inefficient, therefore, as was suggested in the beginning put the attributes in the "Product" model and you will have:
products=Product.objects.filter(size="12")
Refining your model will help you to filter.
With my experience following model approach will be more suitable:
class Attributes(models.Model):
name = models.CharField(max_length=50, default=None)
slug = models.SlugField(max_length=200, unique=True,null=True)
class AttributeTerms(models.Model):
name = models.CharField(max_length=50, blank =True)
attribute = models.ForeignKey(Attributes, on_delete=models.CASCADE)
class Products(models.Model):
name = models.CharField(max_length=250,null=True, blank=True,)
slug = models.SlugField(max_length=200, unique=True,null=True)
class ProductAttribute(models.Model):
product = models.ForeignKey(Products,on_delete=models.CASCADE, related_name='attributes', default=None)
attributes = models.ForeignKey(Attributes,on_delete=models.CASCADE, related_name='attributes', default=None)
values = models.ForeignKey(AttributeTerms, on_delete=models.CASCADE, related_name='attributes', default=None)
class ProductVariant(models.Model):
product = models.ForeignKey(Products,on_delete=models.CASCADE)
variant = models.ForeignKey(ProductAttribute,on_delete=models.CASCADE, null = True, default=None)
stock = models.IntegerField(default=None)
stock_threshold = models.IntegerField()
price = models.DecimalField(max_digits=10, decimal_places=2)
sku = models.CharField(max_length= 250, default=None)
sale_price = models.DecimalField(max_digits=10, decimal_places=2)
This is the full task :
Export a list of customers who completed registration but haven't performed any action (no invoice, expense, withdrawal) last week (3-9 May)
I need to create this type of SQL, but I don't know how to check for actions, what I did for now is
SELECT user FROM users_user
WHERE completed_registration=False
AND date_joined BETWEEN '2021-05-03 00:00:00' AND '2021-05-29 00:00:00'
UNION
SELECT user FROM invoice_invoice;
Check for users who had completed the registration, check for the date, and then check the invoice. But as I check for invoice_invoice itself it's an empty table, why do I get one user when I launch this query? The completed_registration and the date fields which are in queryset right now are only for test.
Only users
This is when I check only for invoices
This is the structure:
Expense model:
class Merchant(BaseModel):
company = models.ForeignKey(Company, on_delete=models.PROTECT, related_name='merchants')
name = models.CharField(max_length=255)
company_code = models.CharField(max_length=255, default='', blank=True)
def __str__(self):
return f'{self.company} {self.name}'
class Expense(Operation):
category = models.CharField(choices=ExpenseCategories.get_choices(), default=ExpenseCategories.GENERAL.name,
db_index=True, blank=True, max_length=255)
merchant = models.ForeignKey(Merchant, on_delete=models.PROTECT, related_name='expenses', blank=True, null=True)
amount = models.PositiveIntegerField(default=0, blank=True, help_text='Only taxable amount. In cents')
full_amount = models.PositiveIntegerField(
default=0,
blank=True,
help_text='Full amount. Most of the time same as amount or bigger. In cents'
)
currency = models.ForeignKey(Currency, on_delete=models.PROTECT, related_name='expenses',
default=settings.DEFAULT_CURRENCY_CODE)
description = models.TextField(default='', blank=True)
is_taxable = models.BooleanField(blank=True, default=True)
from_date = models.DateField(null=True, blank=True, help_text='Start date in case of aggregated bulk creation.')
to_date = models.DateField(null=True, blank=True, help_text='End date in case of aggregated bulk creation.')
receipt_number = models.CharField(blank=True, default='', max_length=255, help_text='Number from receipt.')
Invoice model:
class Invoice(Operation):
customer = models.ForeignKey(Customer, on_delete=models.CASCADE, related_name='invoices')
number = models.CharField(max_length=255)
notes = models.TextField(default='', blank=True)
payment_due = models.DateField()
total = models.PositiveIntegerField(help_text='In cents', default=0)
payment_status = models.CharField(choices=InvoiceStatuses.get_choices(), default=InvoiceStatuses.UNPAID,
max_length=20)
pdf = models.FileField(null=True, blank=True, upload_to='invoices/pdf', max_length=255)
is_sent = models.BooleanField(default=False, help_text="Is pdf invoice sent")
User model:
class User(AbstractUser):
username = None
email = models.EmailField('email address', blank=True)
phone = PhoneNumberField(unique=True)
is_verified = models.BooleanField(default=False)
language = models.ForeignKey(
Language,
default=settings.DEFAULT_LANGUAGE,
on_delete=models.SET_DEFAULT,
)
avatar = models.ImageField(upload_to='users/avatars', null=True, blank=True)
companies = models.ManyToManyField(Company, related_name='users')
active_company = models.OneToOneField(Company, null=True, related_name='active_user', on_delete=models.SET_NULL)
agreement_text = models.TextField(default='', blank=True)
agreement_date = models.DateField(null=True, blank=True)
personal_no = models.CharField(max_length=100, default='', blank=True)
full_name = models.CharField(max_length=255, help_text='Field holds first and last names.', default='', blank=True)
completed_registration = models.BooleanField(default=False)
work_hours_from = models.TimeField(default=settings.DEFAULT_WORK_HOURS_FROM, null=True, blank=True)
work_hours_until = models.TimeField(default=settings.DEFAULT_WORK_HOURS_UNTIL, null=True, blank=True)
You seem to want not exists. I would expect logic like this:
SELECT u.*
FROM users_user u
WHERE u.completed_registration AND
NOT EXISTS (SELECT 1
FROM invoice_invoice i
WHERE i.user = u.user AND
i.invoice_date >= '2021-05-03' AND
i.invoice_date < '2021-05-10'
);
You would repeat this logic for each table where you want to check an action. Also, it is not clear what date you want to use within the invoice table, so I made one up.
I want to check whether the current user already has the same movie id in his personal list or not. If he has it then I want to exclude that movie from my trending list.
I want it to be something like this.
views.py
trending = list(Movies.objects.exclude(mid in mymovies WHERE uid = request.user.id))
models.py
class Movies(models.Model):
mid = models.CharField(max_length=255, primary_key=True)
title = models.CharField(max_length=255, null=True, blank=True)
rating = models.CharField(max_length=5, null=True, blank=True)
type = models.CharField(max_length=255, null=True, blank=True)
genre = models.CharField(max_length=255, null=True, blank=True)
rdate = models.CharField(max_length=255, null=True, blank=True)
language = models.CharField(max_length=255, null=True, blank=True)
cover = models.CharField(max_length=255, null=True, blank=True)
description = models.TextField(null=True, blank=True)
sequal = models.CharField(max_length=255, null=True, blank=True)
trailer = models.CharField(max_length=255, null=True, blank=True)
year = models.CharField(max_length=5, null=True, blank=True)
objects = models.Manager()
def __str__(self) -> str:
return self.title
class MyMovies(models.Model):
mid = models.ForeignKey(Movies, on_delete=CASCADE)
uid = models.ForeignKey(User, on_delete=CASCADE, null=True, blank=True)
watched = models.BooleanField()
date = models.DateTimeField(auto_now_add=True)
objects = models.Manager()
You can .exclude(…) with:
trending = Movies.objects.exclude(mymovies__uid=request.user)
If you specified a related_query_name=… [Django-doc] or a related_name=… [Django-doc], then you need to use that to make a JOIN with your Movies model:
trending = Movies.objects.exclude(related_name_of_fk__uid=request.user)
Note: normally a Django model is given a singular name, so MyMovie instead of MyMovies.
Note: Normally one does not add a suffix _id to a ForeignKey field, since Django
will automatically add a "twin" field with an _id suffix. Therefore it should
be user, instead of uid.
I am new to django and I am trying to make a django view that will bring me certain values from two models, this would be accomplished by doing a join if done directly in sql. What I intend to do with the obtained data is return it as JSON and use this json in an html page. I just don't know how to structure or if there is any way to get the data like sql.
Model device
class device(models.Model):
device_name = models.CharField(max_length=50, unique=True, help_text='Station Name', validators=[validate_slug])
parent_area_id = models.ForeignKey('area', on_delete=models.CASCADE, null=True, help_text='Parent Area')
f2cuid = models.CharField(max_length=100, unique=True, validators=[validate_slug])
ip_address = models.GenericIPAddressField(protocol='both', unpack_ipv4='True', default='127.0.0.1', blank=False, null=False)
tower_ip_address = models.GenericIPAddressField(protocol='both', unpack_ipv4='True', default='127.0.0.1', blank=True, null=True)
layered_tower = models.BooleanField(default=False, blank=True, help_text='Check if tower is multilayer')
layer = models.CharField(max_length=1, unique=False, null=True, default=None, help_text='Layer', choices=layer_choices)
target_oee = models.DecimalField(validators=[MinValueValidator(0), MaxValueValidator(100)], help_text='OEE Target', decimal_places=2, max_digits=6, default=0)
target_availability = models.DecimalField(validators=[MinValueValidator(0), MaxValueValidator(100)], help_text='Availability Target', decimal_places=2, max_digits=6, default=0)
target_performance = models.DecimalField(validators=[MinValueValidator(0), MaxValueValidator(100)], help_text='Performance Target', decimal_places=2, max_digits=6, default=0)
target_quality = models.DecimalField(validators=[MinValueValidator(0), MaxValueValidator(100)], help_text='Quality Target', decimal_places=2, max_digits=6, default=0)
Model notification_radio
class notification_radio(models.Model):
device_id = models.ForeignKey('device', on_delete=models.CASCADE, null=False)
event_id = models.ForeignKey('event', on_delete=models.CASCADE, null=False)
to_address = models.CharField(null=False, blank=False, max_length=100)
message = models.CharField(null=False, blank=False, max_length=100, default='ANDON ALERT')
notification_type = models.CharField(null=False, blank=False, choices=notification_type_choices, max_length=100)
notification_id = models.IntegerField(null=False)
requested_date = models.DateTimeField(null=True)
processed = models.BooleanField(default=False)
processed_date = models.DateTimeField(null=True)
Sentence SQL
SELECT
`and`.`device_name` AS `device_name`,
COUNT(`anr`.`device_id_id`) AS `notif_sended`
FROM
(`andon_notification_radio` `anr`
JOIN `andon_device` `and` ON ((`anr`.`device_id_id` = `and`.`id`)))
WHERE
(`anr`.`processed` = 1)
GROUP BY `device_name`
VIEW Django
def notif_count_by_station(request):
data = notification_radio.objects.all() \
device.objects.all()
return JsonResponse(list(data), safe=False)
This is how you would expect to get the JSON, you would get the device name and the notif_sended grouped by the device_name, it would output the notifications sent by each device_name.
Regards.
You can perform such a query with:
from django.db.models import Count
def notif_count_by_station(request):
data = device.objects.values('device_name').filter(
notification_radio__processed=1
).annotate(
notif_sended=Count('notification_radio')
)
return JsonResponse({'data': list(data)})
Please do not return data wrapped in an outer list, since it can be victim to cross-site request forgery.
i don't know what exactly you are looking foor, but if oy want to get device name and device id where processed =1.
data = Notification_radio.objects.filter(processed=1).values('device_id __device_name').annotate(total=Count('device_id'))