How to select same object twice in Django ManyToMany Field - python

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

Related

Django Rest Framework: Handle Many-to-Many relationship

The requirement is "I want to insert person with the person groups selection and also at the time of Creating person group I can choose persons for that particular group".
I've added two models in my models.py and manage many to many relationship between.
models.py
from django.db import models
class PersonGroup(models.Model):
id = models.AutoField(primary_key=True)
groupName = models.CharField(max_length=30)
detail = models.CharField(max_length=200)
class Person(models.Model):
id = models.AutoField(primary_key=True)
personId = models.CharField(max_length=20)
personName = models.CharField(max_length=20)
state = models.IntegerField()
personGroup = models.ManyToManyField(PersonGroup, related_name="person_list", blank=True)
serializers.py
class PersonSerializer(serializers.ModelSerializer):
personGroup = serializers.PrimaryKeyRelatedField(queryset=PersonGroup.objects.all(), many=True)
class Meta:
model = Person
fields = '__all__'
class PersonGroupSerializer(serializers.ModelSerializer):
person_list = PersonSerializer(many=True, read_only=True)
class Meta:
model = PersonGroup
fields = '__all__'
The above code help me to create person with personGroup selection
But, I also want to add persons selection at the time of create personGroup. Currently at the time of creating personGroup I'm not allowed to enter persons.
Please let me know if there any solution by which I can also select available persons at the time of person group creation.
Your person_list field in the PersonGroupSerializer is on read only, so you can't modify it using the API.
person_list = serializers.PrimaryKeyRelatedField(queryset=Person.objects.all(), many=True)
Try removing this arg.
You might also want to switch to a ForeignKey field instead of slugged.

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.

Django combine foreign keys in a single queryset

I have a model in a Django application that is being referenced by multiple other models as a ForeignKey.
What I am looking for is for a way to create a single queryset for all objects of this class that are being referenced as ForeignKey by the rest of the classes based on some criteria.
I am not even sure if this is possible, but I thought about asking anyway.
class Person(models.Model):
pass
class Book(models.Model):
year_published = models.PositiveIntegerField()
author = models.ForeignKey(Person)
class MusicAlbum(models.Model):
year_published = models.PositiveIntegerField()
producer = models.ForeignKey(Person)
recent_books = Book.objects.filter(year_published__gte=2018)
recent_music_albums = MusicAlbum.objects.filter(year_published__gte=2018)
# How can I create a **single** queryset of the Person objects that are being referenced as `author` in `recent_books` and as `producer` in `recent_music_albums`?
Thanks for your time.
I don't have Django in front of me at the moment, but what about something like:
class Person(models.Model):
pass
class Book(models.Model):
year_published = models.PositiveIntegerField()
author = models.ForeignKey(Person, related_name='books')
class MusicAlbum(models.Model):
year_published = models.PositiveIntegerField()
producer = models.ForeignKey(Person, related_name='albums')
Person.objects.filter(books__year_published__gte=2018, albums__year_published__gte=2018)
Or, if you have to do those first two queries anyway,
Person.objects.filter(books__in=recent_books, albums__in=recent_music_albums)
You will have on Person model instances a RelatedManager for Books and MusicAlbums. Probably they will still have the default names book_set and musicalbum_set since you didn't override them.
You can use these to find the books/music albums associated with one person instance:
persons_books = person.book_set.all()
persons_musicalbums = person.musicalbum_set.all()
And similarly you can generate the relevant queryset from the model manager:
qs = Person.objects.exclude(book=None).exclude(musicalbum=None)
Same can be achieved by this :
person = Person.objects.latest('book__year_published', 'musicalbum__year_published')
or
personList = Person.objects.all().order_by('-book__year_published', '-musicalbum__year_published')

one-to-many field in Django

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.

Categories

Resources