I have two models:
class City(models.Model):
name = models.CharField(max_length=50, verbose_name='Qyteti')
slug = models.SlugField(unique=True)
class Business(models.Model):
name = models.CharField(max_length=120, verbose_name='emri')
slug = models.SlugField(unique=True)
city = models.OneToOneField(City, verbose_name='qyteti')
created = models.DateTimeField(auto_now_add=True, verbose_name='krijuar')
categories = models.ForeignKey(Category, related_name='businesses', verbose_name='kategoria')
user = models.ForeignKey(User, related_name='user_businesses', verbose_name='autori')
geom = gis_models.PointField(u"longitude/latitude", geography=True, blank=True, null=True)
I want to create a serach like yelp.com
I want people to search in three different ways.
One type of business in all cities.
All type of businesses in one city.
One type of business in one city.
I've tried chain from itertools, but no results so far.
I'd like to do just a simple search for now, not with external search engines.
Anyone's help is appreciated.
You need to do the following:
1) Change in your model:
class Business(models.Model):
city = models.ForeignKey(City, verbose_name='qyteti', related_name='businesses')
2) Queries:
1) one_type = Business.objects.filter(name = "some_business_type").select_related('city')
one_type.city.name
2) one_city_all_business = City.objects.filter(name = "London").prefetch_related('businesses')
one_city_all_business.businesses.all() - here u get a list of all businesses for London
3) one_type_one_city = City.objects.filter(name = "London").filter(businesses__name = "some_business_type").prefetch_related('businesses')
The only problem here - you need to decide how user will select what query to run, I mean how will you define what user wants to search for.
Related
This is a contest system project. I have these models and I know the contest_id and problem_id. I'm trying to return a queryset that contains users who have solved a problem. A user who solves a problem is the one whose submission's score is equal to score of the problem he tried to solve.
At the end I need to sort these users based on the time they have submitted their successful submission.
class Contest(models.Model):
name = models.CharField(max_length=50)
holder = models.ForeignKey(User, on_delete=models.CASCADE)
start_time = models.DateTimeField()
finish_time = models.DateTimeField()
is_monetary = models.BooleanField(default=False)
price = models.PositiveIntegerField(default=0)
problems = models.ManyToManyField(Problem)
authors = models.ManyToManyField(User, related_name='authors')
participants = models.ManyToManyField(User, related_name='participants')
class Problem(models.Model):
name = models.CharField(max_length=50)
description = models.CharField(max_length=1000)
writer = models.ForeignKey("accounts.User", on_delete=models.CASCADE)
score = models.PositiveIntegerField(default=100)
class Submission(models.Model):
submitted_time = models.DateTimeField()
participant = models.ForeignKey(User, related_name="submissions", on_delete=models.CASCADE)
problem = models.ForeignKey(Problem, related_name="submissions", on_delete=models.CASCADE)
code = models.URLField(max_length=200)
score = models.PositiveIntegerField(default=0)
I tried following code but I get wrong answer. How can I sort my QuerySet?
def list_users_solved_problem(contest_id, problem_id):
problem_score = Problem.objects.get(id=problem_id).score
successful_submissions_ids = Submission.objects.filter(
Q(score=problem_score) & Q(problem__id=problem_id)).
values_list('participant__id', flat=True)
return Contest.objects.get(id=contest_id).
participants.filter(id__in=successful_submissions_ids).
order_by('submissions__submitted_time')
You can .filter(…) [Django-doc] with:
from django.db.models import F
User.objects.filter(
participants=contest_id,
submissions__problem_id=problem_id,
submissions__score=F('submissions__problem__score')
).order_by('submissions__submitted_time')
The modeling looks however "strange": the submission is not linked to the contest. So if two (or more) contests share the same problem, then that means it will take the first complete submission to that problem, regardless what the contest is.
Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.
I am fairly new to Django, but I am working on an application that will follow a CPQ flow or Configure, Price, Quote. The user should select the product they would like to configure as well as the options to go with it. Once selected, the program should query an external pricing database to calculate price. From there the program should output the pricing & text data onto a PDF quote. I was able to get the application working using the specific product inheriting from a base product class. The issue is now that I've created a second product child class, I cannot use a singular "related_name". I've omitted the lists associated with the drop down fields to help with readability, but I've posted my models.py file below.
Is there a way I can iterate through Product objects that are pointing to a Quote object with a foreign key? A lot of answers I've found on SO relating to this were able to be solved either by specifying the "_set" or "related_name". I've seen other answers use the select_related() method, however, I can't seem to get the query right as the program won't know which set it needs to look at. A quote could have any mix of product instances tied to it, so am unsure how to handle that query. Again, I have been using django under 6 months, so I am a bit green. I am not sure if I am just not fundamentally understanding the big picture here. I thought about instead of using inheritance, to make Product a standalone class and to save the Compact or WRC info to it so I could just use one "related_name", but also thought that would just create another nested layer that would still fail.
Any help would be very appreciated! I've definitely hit the wall.
models.py
class Quote(models.Model):
project_name = models.CharField(max_length=256,blank=True)
customer_first_name = models.CharField(max_length=256,blank=True)
customer_last_name = models.CharField(max_length=256,blank=True)
company_name = models.CharField(max_length=256, blank=True)
address1 = models.CharField(max_length=256, blank=True, help_text ="Address")
address2 = models.CharField(max_length=256, blank=True)
city = models.CharField(max_length=256, blank=True, default="")
state = models.CharField(max_length=256, blank=True, default="")
zip_code = models.CharField(max_length=256, blank=True, default="")
country = models.CharField(max_length=256, blank=True, default="")
phone = PhoneField(blank=True)
email = models.EmailField(max_length=254,blank=True)
grand_total = models.FloatField(default=0)
create_date = models.DateTimeField(default = timezone.now)
class Product(models.Model):
class Meta:
abstract = True
price = models.FloatField(default=0)
total_price = models.FloatField(default=0)
quantity = models.IntegerField()
quote = models.ForeignKey('quote.Quote', on_delete=models.CASCADE)
quantity = models.IntegerField()
class Compact(Product):
base_size = models.CharField(choices=size, max_length = 256)
filter = models.CharField(choices=filter_list, max_length = 256)
product_name = models.CharField(max_length=256,default="Compact")
class WRC(Product):
base_size = models.CharField(choices=size, max_length = 256)
construction = models.CharField(choices=construction_list, max_length = 256)
outlet = models.CharField(choices=outlet_list, max_length = 256)
product_name = models.CharField(max_length=256,default="WRC")
I was able to figure out my issue, but wanted to answer in case someone came across a similar problem as myself. I was able to get get all product objects attached to a quote instance dynamically by modifying the get_context_data() method of my QuoteDetailView. I also needed to use the django library NestedObjects from django.contrib.admin.utils to grab all related objects to the quote instance. I also added a timestamp field to the Product class to be able to sort them. QuoteDetailView copied below.
class QuoteDetailView(FormMixin,DetailView):
model = Quote
form_class = ProductSelectForm
def get_context_data(self, **kwargs):
### collects related objects from quote
collector = NestedObjects(using=DEFAULT_DB_ALIAS)
collector.collect([kwargs['object']])
### slice off first element which is the quote itself
related_objects = collector.nested()
related_objects = related_objects[1:]
### get context data for qoute object
context = super().get_context_data(**kwargs)
context['now'] = timezone.now()
### if number of list items is above 0, then add them to the context
### and sort by timestamp
if len(related_objects) != 0:
context['items'] = sorted(related_objects[0], key=lambda x: x.timestamp)
return context
Hello guys I have one query in my Django project.
First of all, You can see that I have two Django models named BookSeller and Book
Bookseller model
class BookSeller(models.Model):
user_name = models.CharField(max_length=200)
user_email = models.CharField(max_length=200)
user_password = models.CharField(max_length=200)
user_phone = models.CharField(max_length=100)
user_photo = models.ImageField(upload_to='book/seller_photos/%Y/%m/%d/', blank=True)
user_address = models.CharField(max_length=300)
user_state = models.CharField(max_length=100)
user_city = models.CharField(max_length=100)
def __str__(self):
return self.user_name
Book Model
class Book(models.Model):
book_owner = models.ForeignKey(BookSeller, related_name='book_seller', on_delete=models.CASCADE)
book_category = models.CharField(max_length=200)
book_title = models.CharField(max_length=200)
book_price = models.IntegerField()
book_edition = models.CharField(max_length=200)
book_author = models.CharField(max_length=200)
book_old = models.IntegerField()
book_page = models.IntegerField()
book_description = models.TextField(max_length=200)
book_image_1 = models.ImageField(upload_to='book/book_photos/%Y/%m/%d', blank=True)
book_image_2 = models.ImageField(upload_to='book/book_photos/%Y/%m/%d', blank=True)
book_image_3 = models.ImageField(upload_to='book/book_photos/%Y/%m/%d', blank=True)
book_image_4 = models.ImageField(upload_to='book/book_photos/%Y/%m/%d', blank=True)
def __str__(self):
return self.book_title
Want to DO: In my project I want to find books by that book seller's city.
For example, if I write city name 'Silicon Valley' in my search field then it should show me all "Books" that's Sellers(BookSeller) belonging to Silicon Valley.
Query: So my query is how can I do that Django Query set, because I can't find out any query which can do this task.
If you guys have any other solution then please suggest me!!!
For finding the books by some book seller's city you can simly filter the Book instances like so:
Book.objects.filter(book_owner__user_city="Silicon Valley")
One other problem I noticed is that I think you misunderstand related_name attribute in ForeignKey.
The related_name attribute specifies the name of the reverse relation from the BookSeller model back to Book model.
If you don't specify a related_name, Django automatically creates one using the name of your model with the suffix _set.
For instance more appropriate related name in your FK would be books, and without defining it would default to book_set.
book_owner = models.ForeignKey(BookSeller, related_name='books', on_delete=models.CASCADE)
Here is an example, lets assume you have 1 instance of BookSeller and 2 isntances of Book with FK to that instance of BookSeller.
my_book_seller = BookSeller(...)
my_book_1 = Book(book_owner=my_book_seller, ...)
my_book_2 = Book(book_owner=my_book_seller, ...)
Now in your case doing the my_book_seller.book_seller.all() (since you defined the related_name to be book_seller) would return you the two Book instances belonging to my_book_seller. This doesn't make much sense.
On the other hand having the related_name='books' you would get the same books by doing my_book_seller.books.all().
You can find more info in docs.
You can do that like this
Book.objects.filter(book_owner__user_city="Silicon Valley")
and you learn more about various kinds of joining at
this link
You can get the desired results doing something like
books_by_seller_city = Book.objects.filter(book_owner__user_city='Silicon Valley')
Note the use of __ which tells the ORM to look at the referenced model attribute.
You can do with q look ups also, in that case you can add more fields in your query.
queryset = Book.objects.filter(Q(book_owner__user_city__icontains=query)|
.................)
I'm confused with my django models,
My models:
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
bio = models.TextField(max_length=500, blank=True)
location = models.CharField(max_length=30, blank=True)
birth_date = models.DateField(null=True, blank=True)
picture = models.ImageField(upload_to="photos/", default="photos/none/default.png")
film = models.ManyToManyField(Film)
class Film(models.Model):
title = models.CharField(max_length=60)
year = models.IntegerField(choices=YEARS)
image = models.ImageField(upload_to="images/", default="images/none/blank_poster.jpg")
def __str__(self):
return self.title
and now I trying to make a ratings for my film, when user adding a film to his list.
I tried M2M with through, but it wasn't exactly what I wanted, because user could add the same film several times and another problem with it was remove single film from list.
Now i thinking about additional models like this:
class FilmRating(models.Model):
user = models.ForeignKey(User)
film = models.ForeignKey(Film)
rate = models.IntegerField(choices=CHOICES)
Im glad If you can point me to the correct way to solve this problem, In future I want probably to store all rating from users for set average rate.
I have two fields in my model.py one has multi choice drop down and one that is empty. What I would like to have is that if the user select "Gas" from the menu for type, I would like the amount field to get auto populated with distance * 2
Can I do that?
CHOICE = (
('Meal', 'Meal'),
('Gas', 'Gas'),
)
type = models.CharField(max_length=10, choices=CHOICE)
distance = models.CharField(max_length=100)
amount = models.CharField(max_length=100)
Thanks in advance.
You can use the django-observer app for this. Although there are cleaner Javascript approaches, you can make the automation totally depend on Django.
First, modify the amount field as:
amount = models.CharField(max_length=100, blank=True, null=True)
since it won't take any values when the model object is initially saved to the database. Then the rest of the code will look something like:
from observer.decorators import watch
def compute_amount(sender, obj, attr):
if obj.type == 'Gas':
obj.amount = obj.distance * 2
obj.save()
#watch('type', compute_amount, call_on_created=True)
class FuelConsumption(models.Model):
CHOICE = (
('Meal', 'Meal'),
('Gas', 'Gas'),
)
type = models.CharField(max_length=10, choices=CHOICE)
distance = models.CharField(max_length=100)
amount = models.CharField(max_length=100, blank=True, null=True)