Django modeling with filmography - django

I'm still a beginner in django, and I'm working on a small project.
Lets say I have a list full of actors/actresses along what films they've been in. I also have another list of films with specific details of the film such as date of release, casts, credits etc.
The main goal of the app is to be able to search a specific person and pull up the details of all their films.
So for the models right now I have:
class Person(models.Model):
name = models.TextField()
class Film(models.Model):
name = models.TextField()
year = models.IntegerField
The Film model will have a lot more information, but I'm not exactly sure how to link the two. For example I want a user to be able type in "Tom Hanks" and then have the details for his 5 most recent movies displayed.
So for the Person model should I add some field that has a list of their films as foreign key somehow, or is there a better way?
Thanks for the help.

models.py
class Person(models.Model):
name = models.TextField()
class Film(models.Model):
name = models.TextField()
year = models.IntegerField()
actors = models.ManyToManyField('Person')
and then access the film actors using the following command
#first get the film from db
f = Film.objects.all()[0] #get the first Film entry
actors = f.actors.all()

Related

How to call a a field of one model A into another model B so that b can work as a view

I have created a model called Department, Course. Models are as follow
This is the model for departments and course
class Departments(models.Model):
Department_Id = models.IntegerField(primary_key=True)
Department_Name = models.CharField(max_length=200)
Department_Code = models.CharField(max_length=200)
class Course(models.Model):
Course_Id = models.IntegerField(primary_key=True)
Department_Id = models.ForeignKey(Departments, on_delete=models.CASCADE)
Course_Name = models.CharField(max_length=200)
Course_Code = models.CharField(max_length=200)
I want to create a model called view which can be later on called for search. I want a view model in a such a way that it consit of the data in concat form i.e. name= Department_name+ Course_Name
class View (models.model):
view_id= models.IntegerField(primary_key=True)
Name= Department_name(I want this from Departments table)
+ Course_Name(I want this from Course table)
I try using one to one relation . I would really appricate the help
It's not clear why you'd want to do that. It's never a good idea to duplicate data from one model into another one, as it can lead to inconsistencies.
You can add a ForeignKey in View to your Course model and then when you do f"{view.course.name} {view.course.department.name}" you already have your string:
class View(models.Model):
course = models.ForeignKey(Course, on_delete=models.CASCADE)
def name(self):
return f"{self.course.name} {self.course.department.name}"
Notes:
Don't call your foreign key Department_id because it's not referring to the id but to the object itself in the Django ORM: department = models.ForeignKey(Department, on_delete=models.CASCADE). As you can see, this makes reading the code much simpler: self.course.Department_id is a Department object not an integer, so self.course.department makes more sense.
Don't prefix your field names with the class, it just makes the code so much less readable: Do you prefer department.name or department.Department_name?
The View model is still a mystery to me, as you can search without it. You can search for example for courses with a matching department name like this:
Course.objects.filter(department__name__icontains="maths")
which will return all courses with "maths" in their department name.
Remove all the ids from your models, they are created automatically by Django anyway (and called id). Again, department.id is much easier to read than department.Department_id. Also in your code, you have to generate the ids yourself since you don't set them to auto-populate.

Filter based on mutually related models

I have Three models
class Song(models.Model):
title = models.CharField(max_length=100)
bandname = models.ManyToManyField(Band)
albumname = models.ManyToManyField(Album)
class Band(models.Model):
title = models.CharField(max_length=100)
class Album(models.Model):
title = models.CharField(max_length=100)
Now I wants to list all albums for a particular band.
I've tried this way, in view.py
band = Band.objects.get(id=no)
song_list = band.song_set.all()
album = [i.bandname for i in song_list]
It's not working. Please help me.
It seems what you're actually trying to get is a list of all the albums that contain songs by a particular band, either exclusively or in duet. Here's how you could get that using your existing models:
band = Band.objects.get(id=target_band_id)
song_list = Song.objects.filter(bandname=band)
album_list = Album.objects.filter(song__in=song_list).distinct()
Check "Reverse m2m queries" within the Django Many to Many docs.
I would also suggest re-naming bandname and albumname to simply band and album because they are referring to band or album model instances, not the actual names of the band or album. That would get confusing later on if you wanted to add a name field to either the Band or Album models.

Defining a two way many to many in Django

Just starting in Python/Django framework so sorry if this is dumb... but i cant find any solution.
class Dealer(models.Model):
name = models.CharField(max_length=200)
contacts = models.ManyToManyField(Contact)
class Contact(models.Model):
name = models.CharField(max_length=200)
dealers = models.ManyToManyField(Dealer)
I have this relation set up however when I run SyncDB it doesnt work. It tells me that Contact is not defined on this line
contacts = models.ManyToManyField(Contact)
Im more familiar with compiled languages. Is there anyway to tell python that the contact class exists, or better yet is there a special syntax im missing for defining this kind of relation.
I dont see a need for a two way ManyToMany in both the models, as they are a M:N relationship (2 way relationship).
Your issue here is, Contact is not defined at the point of execution of this code:
contacts = models.ManyToManyField(Contact)
So You need to wrap it in quotes for it to work
contacts = models.ManyToManyField('Contact')
Documentation on that can be found here
I would recommend the following models:
class Dealer(models.Model):
name = models.CharField(max_length=200)
contacts = models.ManyToManyField('Contact')
class Contact(models.Model):
name = models.CharField(max_length=200)
and It would do exactly what you are looking for.
You can read about ManyToMany relationships here. The same link also covers how to handle Reverse m2m queries
If you want to do a two way ManyToMany both, you just only need to do this:
class Dealer(models.Model):
name = models.CharField(max_length=200)
contacts = models.ManyToManyField('Contact', blank=True)
class Contact(models.Model):
name = models.CharField(max_length=200)
dealers = models.ManyToManyField('Dealer', through=Dealer.projects.through, blank=True)
I guess it will work to you.

Django: distinct QuerySet based on a related field

In my Django app I allow users to create collections of movies by category. This is represented using 3 models, Movie, Collection, and Addition (the Addition model stores movie, collection, and user instances). Simplified versions of all three models are below.
class Movie(models.Model):
name = models.CharField(max_length=64)
class Collection(models.Model):
name = models.CharField(max_length=64)
user = models.ForeignKey(User)
class Addition(models.Model):
user = models.ForeignKey(User)
movie = models.ForeignKey(Movie)
collection = models.ForeignKey(Collection)
So for example a user could create a collection called "80's movies", and add the movie "Indiana Jones" to their collection.
My question is: how do I display a distinct list of movies based on a set of query filters? Right now I am getting a bunch of duplicates for those movies that have been added to more than one collection. I would normally use distinct() to get distinct objects, but in this case I need distinct movies rather than distinct additions, but I need to query the Addition model because I want to allow the user to view movies added by their friends.
Am I setting up my models in an optimal way? Any advice/help would be much appreciated.
Thanks!
First. I don't think you need Addition model here. You try to create many-to-many relation, but there's documented way of doing this:
class Movie(models.Model):
name = models.CharField(max_length=64)
class Collection(models.Model):
name = models.CharField(max_length=64)
user = models.ForeignKey(User)
movies = models.ManyToManyField('Movie', blank=True, null=True)
Second. The documentation says: "To refer to a "reverse" relationship, just use the lowercase name of the model".
So the answer is (for the setup above):
Movie.objects.filter(collection__user=user).distinct()

about cacade foreignkey in django admin page

My model is like below:
class Manufacturers(models.Model):
name = models.CharField()
class Phones(models.Model):
manufacturer = models.ForeignKey(Manufacturers)
name = models.CharField()
class Prices(models.Model):
phone = models.ForeignKey(Phones)
price = models.DecimalFeild()
and I have registered them in the admin.py
My problem is:
In django's admin interface, When I add a price, I can select a phone from the dropdown list, But there are so many phones, So I want to select the manufacturer at first, then select the phone from the manufacturer's phones. How can I make this.
Thanks very much.
The term for this is "chained select menus".
There are a number of implementations in django. One that you may find useful is django-smart-selects.
Using django-smart-selects, this is how you would write up your models:
class Manufacturers(models.Model):
name = models.CharField()
class Phones(models.Model):
manufacturer = models.ForeignKey(Manufacturers)
name = models.CharField()
class Prices(models.Model):
phone = ChainedForeignKey(
Phone,
chained_field="manufacturer",
chained_model_field="manufacturer",
show_all=False,
auto_choose=True
)
price = models.DecimalField()
All that said, I wonder if you are implementing this in the best fashion.
It might be better to have Prices show up under the admin form for each phone. So instead of creating a price record and choosing the phone from a drop-down, you'd go into the record for that phone and add a price record. See django's documentation on InlineModelAdmin.