one-to-many field in Django - python

I've got this class:
class PurchaseOrder(models.Model):
product = models.CharField(max_length=256)
dollar_amount = models.FloatField()
item_number = models.AutoField(primary_key=True)
I'm trying to make it so that 'product' has a one to many field. In other words, whenever I am adding a new item in django's default admin page. I want to be able to have the option of putting multiple 'product' for the same dollar amount and item number.
In response to Hedde van der Heide's comment. Would this be how you implement this?
class PurchaseOrder(models.Model):
product = models.ManyToManyField(Order)
dollar_amount = models.FloatField()
item_number = models.AutoField(primary_key=True)
class Order(models.Model):
order_product = models.CharField(max_length =256)
def __unicode__(self):
return self.order_product

No, your edit is incorrect. That would imply a purchase order could belong to many orders and vice versa, which makes no sense. You want a simple ForeignKey from PurchaseOrder to Order.

Related

Get max value from a set of rows

This question is in relation to project 2 of the cs50 course which can be found here
I have looked at the following documentation:
Django queryset API ref
Django making queries
Plus, I have also taken a look at the aggregate and annotate things.
I've created the table in the template file, which is pretty straight forward I think. The missing column is what I'm trying to fill. Image below
These are the models that I have created
class User(AbstractUser):
pass
class Category(models.Model):
category = models.CharField(max_length=50)
def __str__(self):
return self.category
class Listing(models.Model):
owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
title = models.CharField(max_length=200)
description = models.TextField()
initial_bid = models.IntegerField()
category = models.ForeignKey(Category, on_delete=models.CASCADE)
date_created = models.DateField(auto_now=True)
def __str__(self):
return self.title
class Bid(models.Model):
whoDidBid = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
list_item = models.ForeignKey(Listing, default=0, on_delete=models.CASCADE)
bid = models.IntegerField()
category = models.ForeignKey(Category, on_delete=models.CASCADE)
date = models.DateTimeField(auto_now=True)
def __str__(self):
return_string = '{0.whoDidBid} {0.list_item} {0.bid}'
return return_string.format(self)
This is the closest I could come to after a very long time. But the result I get is just the number 2. Ref image below
Listing.objects.filter(title='Cabinet').aggregate(Max('bid'))
Where 'Cabinet' is a Listing object that I have created. And placed two bids on them.
So the question is, how do I get the Maximum bid value(i.e. 110 for this case) for a particular listing? Using the orm. I think if I used a raw sql query, I could build a dict, send it to the template with the queryset. Then while looping through the queryset, get the value for the key, where the key is the name of the listing or something along those lines. Nah, I would like to know how to do this through the ORM please.
Here's answer #1
Bid.objects.filter(list_item__title='Cabinet').prefetch_related('list_item').aggregate(Max('bid'))
What happens when you try this (sorry, I don't have any objects like this to test on):
Bid.objects.values(list_item__title).prefetch_related('list_item').annotate(Max('bid'))

How to select same object twice in Django ManyToMany Field

I have two models
class Food(models.Model):
name = models.CharField(max_length=200 ,null=False)
class Profile(models.Model):
food_selected_today = models.ManyToManyField(Food,related_name = 'inventory')
Now in profile model I want to have one food with same id for example Apple more than one time in food_selected_today. If I now add same food twice it only shows one Item. How can I add one food many times here.
Any kind of help would be really appreciated
Generally this is not possible natively with the built in relationship fields, but you can use your own through-model to give you the opportunity to have a count attribute for each relation:
class Food(models.Model):
name = models.CharField(max_length=200, null=False)
class Profile(models.Model):
food_selected_today = models.ManyToManyField(Food,
related_name='inventory',
through='ProfileFood')
class ProfileFood(models.Model):
food = models.ForeignKey(Food)
profile = models.ForeignKey(Profile)
count = models.IntegerField()

I want to access parent model fields using child model object in django

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)|
.................)

Django Designing Model : Item/Inventory/User

I would like to ask some advice on Modeling a specific model behavior.
Basically I have a model Item. It describes the name and description of an item.
I have a inventory, which should hold a "List" of items, considering the quantity of each item should be specified in the inventory.
Each User should have one unique inventory.
Here's what I'm trying to do:
class User(models.Model):
name = models.CharField(max_length=100)
invetory =models.ForeignKey(inventory,on_delete=models.CASCADE)
class item(models.Model):
name =models.CharField(max_length=40)
description = models.TextField(max_length=200)
value = models.FloatField()
class inventory(models.Model):
?
I'm not sure if this is the right approach.
You should use many-to-many relations. First of all you should delete the FK from the User model. Then create a separate model for items and finally link many users to many items (one user can handle multiple items and one item can belong to multiple users). Something like that:
class User(models.Model):
name = models.CharField(max_length=100)
class item(models.Model):
name =models.CharField(max_length=40)
class inventory(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
item = models.ForeignKey(item, on_delete=models.DO_NOTHING)
quantity = models.FloatField()
PS Class names should use PascalCase convention https://www.python.org/dev/peps/pep-0008/?#class-names
class User(models.Model):
name = models.CharField(max_length=100)
class Inventory(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE)
class Item(models.Model):
name =models.CharField(max_length=40)
description = models.TextField(max_length=200)
value = models.FloatField()
invetory =models.ForeignKey(Inventory,on_delete=models.CASCADE)
This should work as per your specification. We have tied up inventory to a user and each item will have a foreign key to Inventory table.
Now you can do
1. To access inventory you can do `user.inventory`
2. To get a list of items `user.inventory.item_set`
3. You should use the `post_save` signal to create the inventory object.
class inventory(models.Model):
user = models.ForeignKey(User, default=User.objects.first())
item = models.ForeignKey(Item, default=Item.objects.first())
count = models.IntegerField(default=0)
I think this would make a better design.

Best way to store category and subcategories of an item in Django models

I want to store something like an Apple which will be stored as "Tree Fruit - Apple - Fuji - Organic" while there will be some items with more categories like Wheat which is "Cereal Grain - Wheat - Soft White Winter - Stephens - Organic".
class Item(models.Model):
user = models.ForeignKey(User)
type = models.CharField(max_length=100, default=None ,blank=True) #Cereal Grain
commodity = models.CharField(max_length=100, default=None ,blank=True) #Wheat
cl = models.CharField(max_length=100, default=None ,blank=True) #Soft White Winter
variety = models.CharField(max_length=100, default=None ,blank=True) #Stephens
market = models.CharField(max_length=100, default=None ,blank=True) #Organic
def __str__(self):
return u"%s" % (self.user)
class Shorten_Item(models.Model):
user = models.ForeignKey(User)
type = models.CharField(max_length=100, default=None ,blank=True) #Tree Fruit
commodity = models.CharField(max_length=100, default=None ,blank=True) #Apple
variety = models.CharField(max_length=100, default=None ,blank=True) #Fuji
market = models.CharField(max_length=100, default=None ,blank=True) #Organic
def __str__(self):
return u"%s" % (self.user)
There will cost items associated reference to those tables.
class User_Variable_Items(models.Model):
#variety = models.ForeignKey(User_Variety)
category = models.CharField(max_length=100,default=None ,blank=True)
sub_category = models.CharField(max_length=100,default=None ,blank=True)
item = models.CharField(max_length=100,default=None ,blank=True)
price = models.DecimalField(max_digits=20,decimal_places=2,default=None ,blank=True)
unit = models.CharField(max_length=100,default=None ,blank=True)
quantity = models.FloatField(default=0,blank=True)
total = models.DecimalField(max_digits=20,decimal_places=2,default=None ,blank=True)
class Meta:
verbose_name_plural = _("User_Variable_Items")
class User_Fixed_Items(models.Model):
#variety = models.ForeignKey(User_Variety)
category = models.CharField(max_length=100,default=None ,blank=True)
price = models.DecimalField(max_digits=20,decimal_places=2,default=None ,blank=True)
unit = models.CharField(max_length=100,default=None ,blank=True)
quantity = models.FloatField(default=0,blank=True)
total = models.DecimalField(max_digits=20,decimal_places=2,default=None ,blank=True)
class Meta:
verbose_name_plural = _("User_Fixed_Items")
What would be the best way to have the User_Variable_Cost_Items and User_Fixed_Cost_items to reference to one of the table above (not both)?
Thanks
I think what you are trying to do is:
To have a type of item, from a certain category, that can be on a inheritance hierarchy. Itens can have diferent types and make diferent things, this sounds like a inheritance structure (e.g Item > PriceFixedItem and Item > VariablePriceItem).
On this way you can try to compose a data structure to store and recover the data from a database. Can you try to do something like this:
Create a Model that refers to himself, to make a tree of categories, can be anything like:
class Category(models.Model):
parent = models.ForeignKey('self') # Here category will refer to it self
name = models.CharField()
Now your items can refer to only one category, and you can turn the things here more dynamics:
class Item(models.Model):
category = models.ForeignKey(Category)
name = models.CharField()
price = models.FloatField()
We are going now to have different types of items:
class FixedPriceItem(Item):
pass
class VariablePriceItem(Item):
price_tax = models.FloatField()
The best for now is that how we have this structure, Django can solve the problems you have, but how? That's simple, look this:
class UserItem(models.Model):
item = models.ForeignKey(Item)
From now you have one single object type to manage user items, that's very good to maintain. The most important thing i can see here is that you are trying to solve this problem on a database's structure, but when you are programming over an ORM framework like on Django, you don't have to care too much about you database structure, you need to solve your problems on the programming language, Python on this case, so its simple to solve that problem using OO concepts, like this one. Other important thing is a concept that you have to keep in mind for all your life: The object who have the data, is the object who cares about the data. If you implement this your control logic on the wrong place, you will have to write much more, and cry much more, in this example, you have to let the Item objects to care about like they will present, calculate or store his data. Don't try to implement the controls on User's classes, this will be very valuable when you will have another type of item, and you will need to put one more if to verify if uses this item like this or that.
If you can reorganize your models, you can make use of models inheritance (https://docs.djangoproject.com/en/1.8/topics/db/models/#model-inheritance)
Your Item model could have been a sub class of Shorten_Item, given that it only contains one extra field, the cl = CharField()
You can keep Shorten_Item as it is, then make Item inherit from that model:
class Item(Shorten_Item):
cl = models.CharField(max_length=100, default=None ,blank=True)
Now in your other class,
class User_Variable_Items(models.Model):
...
# Add a foreign key to the base Item class
# Which by inheritance can contain both keys from Shorten_Item and Item
item = ForeignKey('Shorten_Item')
When you retrieve the ID of the Shorten_Item, use your business logic to determine if you want to use it as Shorten_Item or Item (by downcasting it to Item when needed)
If you cannot reorganize your models to benefit from inheritance, your only solution might be to use an item_id = IntegerField() as a "foreign key" that will be able to point to any table, and you'll have to write some more queries yourself

Categories

Resources