I'm working on my first django project which is a sport betting app.
My models are:
class Game(models.Model):
home_team = models.CharField(max_length=100)
away_team = models.CharField(max_length=100)
class GameResult(models.Model):
gameid = models.ForeignKey(Game)
result = models.IntegerField(default=None)
class GameBet(models.Model):
gameid = models.ForeignKey(Game)
bet = models.IntegerField(default=None)
userid = models.ForeignKey(User)
I'm trying to create a view that shows only pending games, which means they have no result (easy part) and no bet placed yet.
Here the problem is - in my database I have only bets that was made, like:
gameid| userid | userbet
23 | 10 | 2
23 | 11 | 1
23 | 12 | 0
and I'm looking for somethig like this:
gameid| userid | userbet
24 | 10 | 1
24 | 11 | 0
When userid #12 hasn't made his bet yet - so it is missing in the database and game should be in his pending games list.
My current logic is that I know ids of all games, I know ids of games with result and I know ids of games that I placed my bet.
How do I connect these dots and find out games that I still have to bet?
all_games = Game.objects.get()
games_with_result = GameResult.objects.filter(result__isnull=False)
games_with_players_bet = GameBet.objects.filter(userid_id=selected_player)
Or maybe I should rebuild my database? I appreciate all the answers
You might use exclude on a queryset:
all_games = Game.objects.all()
results = GameResult.objects.filter(result__isnull=False)
games_without_result = all_games.exclude(pk__in=[r.gameid.pk for r in results])
bets_from_player = GameBet.objects.filter(userid_id=selected_player)
owing_games = games_without_result.exclude(pk__in=[bet.gameid.pk for bet in bets_from_player])
The GameResult model might move as a field (result = models.IntegerField(default=None)) into Game. This should work as long as you only expect one result per game. As a benefit you can easily query for games without results.
games_without_result = Game.objects.filter(result__isnull=True)
Related
I have data in the following form:
collection_name | type | manufacturer | description | image_url
---------------------------------------------------------------------------
beach | bed | company a | nice bed | 1.jpg
beach | king bed | company a | nice bed | 1.jpg
beach | nightstand | company a | nice ns | 1.jpg
grass | chest | company a | nice chest | 2.jpg
apple | chest | company a | nice chest | 3.jpg
fiver | chest | company b | good chest | 4.jpg
What I need to do, is select all images and only return each image once (distinct), but then return non-distinct row for each image.
My goal is to ensure I display each image only once in my template, but show all records associated with each image.
In the example above, 1.jpg is one image that would show both beds and the nightstand in one image. I would like to show such an image and list associated products with it.
I have seen similar questions, although asking at the SQL/db level and not asking for a pure django solution.
The query I have been using in my view has been something like:
products = product.objects.filter(collection_name=name)
and then iterating over products, retrieving image_url like so:
{% for instance in products %}
{{ instance.image_url }}
{{ endfor }}
I've tried various attempts to limit repeating images in my template, but none have really worked, and attempts to do so in my view have not been successful.
What is the correct way to approach this?
Edit: A relevant excerpt from my models to match the sample data above:
class Product(models.Model):
collection_name = models.TextField(null='true',blank='true')
type = models.TextField(null='true',blank='true')
manufacturer = models.TextField(null='true',blank='true')
description = models.TextField(null='true',blank='true')
image_url = models.TextField(null='true',blank='true')
Edit: My idea of views and logic to attempt to solve this, after reading the docs and looking at other questions (no answers):
Pass the product_id of any product in a collection to the view. Then obtain the collection_name field of a record based on the id field:
collectionname = product.objects.filter(id=id).values('collection_name').distinct()
Then, when we have the collection_name field, return all products for a given collection_name:
products = product.objects.filter(collection_name__in=collectionname)
Then, finally, return a list of image_url results for a given collection name, removing duplicates:
images = product.objects.filter(collection_name__in=collectionname).values('image_url').distinct()
I think this should work, in theory...
Edit:
Currently attempting the following based on Juancarlos' answer below:
products = product.objects.filter(collection_name=name)
collectionname = product.objects.filter(id=id).values('collection_name').distinct()
images = product.objects.filter(collection_name__in=collectionname).values("image_url").distinct()
results = []
for img in images:
pbis = product.objects.filter(collection_name__in=collectionname, image_url=img['image_url'])
obj = {"image": img['image_url'], "items":[{"type":pbi.type} for pbi in pbis]}
results.append(obj)
mabe this logic can help you, i am not sure but you can do something like this:
images = product.objects.filter(collection_name=name).values("image_url").distinct()
results = []
for img in images:
pbis = product.objects.filter(collection_name=name, image_url=img['image_url'])###this get all record tha contains this image
obj = {"image": img['image_url'], "items":[{"attr":pbi.attr, ...} for pbi in pbis]}
results.append(obj)
###this iterate all record by images and you can store items attribute from all recors that contains that image
You need tell to django what field you want distinct, you can use values to do that:
in your case your answer can seen like this:
products = product.objects.filter(collection_name=name).values("image_url").distinct()
I am trying to create a trip monitoring app whereas each trip is given a ticket and particular origin and destination. What I want to do now is that given a date range, I would like to know how many trips are made for the unique origin-destination pair.
I have not found solutions to this yet and I'm hoping that somebody could enlighten me on this.
Here is my models:
class Location(models.Model)
name = models.Charfield(max_length=50, unique=True)
...
class Trip(models.Model):
ticket = models.PositiveIntegerField(primary_key=True, blank=False, null=False)
origin = models.ForeignKey(Location, on_delete=models.CASCADE)
destination = models.ForeignKey(Location, on_delete=models.CASCADE)
...
I am expecting the following output which I currently don't know what to do:
Origin | Destination | Number of Trips
Place #1 | Place #2 | 5
Place #2 | Place #1 | 3
Place #3 | Place #1 | 8
Place #3 | Place #2 | 1
Let me post the answer from the comment...
Trip.objects.values('origin', 'destination').distinct().annotate(trips=Count('origin'))
Try with:
query = Trip.objects.values('origin', 'destination').annotate(count=Count('pk'))
for trip in query:
print(trip['origin'], trip['destination'], trip['count'])
If you want to get the names of the locations instead of the ids:
query = Trip.objects.values('origin__name', 'destination__name').annotate(count=Count('pk'))
for trip in query:
print(trip['origin__name'], trip['destination__name'], trip['count'])
This is called aggregation in Django docs, you can find many more examples there:
https://docs.djangoproject.com/en/2.0/topics/db/aggregation/
I have huge table that needed to be sliced into some smaller table, ex:
campaign_01, campaign_02, ...
While using django queryset with different table name for same model, what I only know to set table name on a model is:
Model._meta.db_table = 'tableXXX'
However this method doesn't work in single shell/request. (only work for first time, but not for the next) -> maybe because it still on same instance?
After the second time we tried to set _meta.db_table = 'tableYYY', it will occur an error "django.db.utils.ProgrammingError: missing FROM-clause entry for table "tableXXX""
I also have tried some suggestion I read for this problem answer like:
class ListingManager(models.Manager):
def get_custom_obj(self, table_name):
self.model._meta.db_table = table_name
return self
class ObjectName(models.Model):
objects = ListingManager()
Try to create an Object manager to get new object, but it not work, it still throw same error as before (on the second time setting _meta.db_table)
The only way to make it work if we want to set multiple times for _meta.db_table is we need to exit() the shell first, then re-enter the shell mode (which means for loop is not gonna work).
I know it can be achieved with raw query 'Insert into tableXXX values ()', but any method to do it using django queryset? Thanks~
Consider creating a wrapper model.
class Model1(models.Model):
# fields...
name = ...
age = ...
class Model2(models.Model):
# fields...
height = ...
weight = ...
class ModelAll(models.Model):
model1 = models.OneToOneField(Model1)
model2 = models.OneToOneField(Model2)
But if you're only doing this for organization, just break the fields up with white space.
This will result in the following tables:
Model1
id | name | age
------------------
1 | "Joe" | 21
Model2
id | height | weight
----------------------
1 | 5.85 | 175
2 | 6.0 | 210
ModelAll
id | model1_id | model2_id
----------------------------
1 | 1 | 2
To access sub model fields:
modelall = ModelAll.objects.get(...)
modelall_name = modelall.model1.name
modelall_height = modelall.model2.height
I'd like to create a Django project for my company's purchasing department. This would be my first project in Django, so sorry if this comes off as rudimentary. The workflow would look something like this:
user registers for an account > signs in > can create, edit, view, or delete a purchase order.
I'm getting tripped up on the modeling. Presumably I can create and authenticate users using django.contrib.auth. Also, since this is mainly a form saving/printing application I would use a ModelForm to generate my forms based on my models since the users will be making changes to the form data that will need to be saved. A simplified version of the purchase order form in question looks something like this:
| Vendor | Date | Lead Time | Arrival Date | Buyer_Name |
+--------+-------+-----------+--------------+------------+
| FooBar |1-1-12 | 30 | 2-1-12 | Mr. Bar |
+--------+-------+-----------+--------------+------------+
+--------+-------+-----------+--------------+------------+
| SKU | Description | Quantity | Price | Dimensions |
+--------+-------------+----------+-------+--------------+
|12345 | Soft Bar | 38 | 5.75 | 16 X 5 X 8 |
+--------+-------------+----------+-------+--------------+
|12346 | Hard Bar | 12 | 5.75 | 16 X 5 X 8 |
+--------+-------------+----------+-------+--------------+
|12347 | Medium Bar | 17 | 5.75 | 16 X 5 X 8 |
+--------+-------------+----------+-------+--------------+
As you can see, the main purchase order form has a header that identifies the Vendor being ordered from, the current date, lead time, arrival date, and the buyer's name who is filling the form out. Under that is a line-by-line order detail for three different SKUs. Ideally, each PurchaseOrder should be able to have many SKUs added to it.
What is the best way to model something like this? Do I create a User, PurchaseOrder, and SKU model? Then add a FK to the SKU Model that points to the PurchaseOrder Model's PK or is there some other, more correct, way to do something like this? Thanks in advance for any help.
[Edit]
Django had what I was looking for all along. Since this is essentially a nested form, I could make use of Formsets.
Here are two helpful links to get started:
https://docs.djangoproject.com/en/1.4/topics/forms/formsets/
https://docs.djangoproject.com/en/1.4/topics/forms/modelforms/#model-formsets
Use django's built in user model (you can look at the source to see the definition but it is similar to the code below for these other models). Other than that I would suggest a model for every object you mentioned.
Don't add a FK to the SKU Model since SKU can exist without being in a purchase order (if I understand the problem correctly).
models.py
from django.contrib.auth.models import User
class Vendor(models.Model):
name = models.CharField(max_length=200)
#other fields
class SKU(models.Model):
description = models.CharField(max_length=200)
#other fields
class PurchaseOrder(models.Model):
purchaser = models.ForiegnKey(User)
name = models.CharField(max_length=200)
skus = models.ManyToManyField(SKU) #this is the magic that allows 1 purchase order to be filled with several SKUs
#other fields
I have to get a QuerySet with many-to-many relations with the same number of results as if I executed the query in the database, but can't manage how to do this; I don't care if I can get the results as a QuerySet item or as a values item, but I do care to get the same number of results.
Imagine the following scenario:
class Person(models.Model):
name = models.CharField()
class Car(models.Model):
name = models.CharField()
class House(models.Model):
people = models.ManyToMany(Person)
cars = models.ManyToMany(Car)
house_1 = House.objects.create()
house_2 = House.objects.create()
john = Person.objects.create(name='John')
mary = Person.objects.create(name='Mary')
house_1.people.add(john)
house_1.people.add(mary)
mike = Person.objects.create(name='Mike')
ferrari = Car.objects.create(name='Ferrari')
house_2.people.add(mike)
house_2.cars.add(ferrari)
'''
Expected search result, regardless of the result format (model instances or values):
------------------------------------
| House ID | Car | Person |
| 1 | | John |
| 1 | | Mary |
| 2 | Ferrari | Mike |
------------------------------------
'''
How can I get a list of values, with all 3 results, spanning multiple tables, as here?
I need this so that I can create a report which can potentialy contain null fields, so the duplicated results must be listed.
Thanks!
Try to write SQL query that does that. You can't because it's wrong query to that data structure. Imagine that there will be 2 cars assigned to house 1. Should it be 1-[car-1]-John, 1-[car-2]-Merry or 1-[car-2]-John, 1-[car-1]-Merry?