Related
I have model name Movie which have many-to-many Relation with Actor Table. Actor Table is further many-to-many relation with Celebrity-Role.
My question is i need only unique values on the base of roles Like Actors who's role is Director they show in Movie Table field with Director and only directors should be there and so on.
i share my models please have a look.
class CelebrityRole(models.Model):
CELEBRITY_CHOICES = (
('Actor', 'Actor'),
('Producer', 'Producer'),
('Writer', 'Writer'),
('Director', 'Director'),
)
role = models.CharField(max_length=8,
choices=CELEBRITY_CHOICES)
def __str__(self):
return self.role
class Actor(models.Model):
GENDER = (
('Male', 'Male'),
('Female', 'Female'),
)
name = models.CharField(max_length=200)
rank = models.CharField(max_length=5, default=0)
gender = models.CharField(max_length=6, choices=GENDER)
avatar = models.ImageField(upload_to='CelebrityGallery/',
blank=True)
description = models.TextField(blank=True)
birth_place = models.CharField(max_length=200, blank=True)
dob = models.DateField(auto_now=False, auto_now_add=False)
height = models.CharField(max_length=20)
is_married = models.BooleanField(default=False)
movies = models.ManyToManyField(
'movies.Movie', related_name='movies', blank=True)
celebrity_role = models.ManyToManyField(CelebrityRole)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name
Here is my Movie Table
class Movie(models.Model):
title = models.CharField(max_length=200)
year = models.CharField(max_length=25, blank=True)
description = models.TextField(blank=True)
released = models.CharField(max_length=25)
runtime = models.CharField(max_length=25)
language = models.CharField(max_length=255)
country = models.CharField(max_length=100)
metascore = models.CharField(max_length=5, blank=True)
imdb_id = models.CharField(max_length=10, blank=False,
unique=True, default='tt3032400')
imdb_rating = models.CharField(max_length=5, blank=True)
imdb_votes = models.CharField(max_length=100, blank=True)
budget = models.CharField(max_length=25)
box_office = models.CharField(max_length=25, blank=True)
imdb_original = models.BooleanField(default=False)
type = models.CharField(max_length=10, blank=True)
season = models.CharField(max_length=2, default=0,
blank=True)
episode = models.CharField(max_length=3, default=0,
blank=True)
poster_url = models.ImageField(upload_to='Posters/',
blank=True)
video_poster_url =
models.ImageField(upload_to='VideoPosters/', blank=True)
video_url = models.TextField(validators=[URLValidator()],
blank=True, max_length=2000)
genre = models.ManyToManyField(Genre,
related_name='genre_movies')
image_gallery = models.ManyToManyField(ImageGallery,
blank=True)
video_gallery = models.ManyToManyField(VideoGallery,
blank=True)
director = models.ManyToManyField(Actor,
related_name='director')
writer = models.ManyToManyField(Actor,
related_name='writer')
actors = models.ManyToManyField(Actor,
related_name='actors')
producer = models.ManyToManyField(Actor,
related_name='producer')
def __str__(self):
return self.title
I'm not sure how you can do it in your models.py. But you can use the filter method in your views.py when making queries to filter actors whose role is director, etc.
I'm trying to get the object "Book" from prommotion. Book is a ForeignKey in "prommotion", and I filtered all the prommotions that are active. I need to get the "Book" object from the Prommotion if its active and return it.
(And I know promotion is spelled wrong)
Views:
class Book_PrommotionViewSet(viewsets.ViewSet):
def list(self, request):
queryset = Prommotion.objects.filter(active=True)
serializer = PrommotionSerializer(queryset, many=True)
return Response(serializer.data, HTTP_200_OK)
Prommotion Model:
class Prommotion(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
precent = models.DecimalField(decimal_places=2, max_digits=255, null=True, blank=True)
active = models.BooleanField(default=False)
date_from = models.DateField()
date_to = models.DateField()
book = models.ForeignKey(Book, on_delete=models.SET_NULL, null=True, blank=True)
country = models.ForeignKey(Country, on_delete=models.SET_NULL, null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
verbose_name = 'Prommotion'
verbose_name_plural = 'Prommotions'
Book Model:
class Book(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
title = models.CharField(max_length=255, null=True, blank=True)
author = models.ForeignKey(Author, on_delete=models.SET_NULL, null=True, blank=True)
price = models.DecimalField(decimal_places=2, max_digits=255)
published = models.DateField()
edition = models.CharField(max_length=255)
isbn_code = models.CharField(max_length=255)
pages = models.IntegerField(blank=True, null=True, default=0)
description = models.TextField(null=True, blank=True)
cover = models.CharField(max_length=30, choices=Cover.choices(), default=None, null=True, blank=True)
genre = models.CharField(max_length=30, choices=Genre.choices(), default=None, null=True, blank=True)
language = models.CharField(max_length=30, choices=Language.choices(), default=None, null=True, blank=True)
format = models.CharField(max_length=30, choices=Format.choices(), default=None, null=True, blank=True)
publisher = models.CharField(max_length=30, choices=Publisher.choices(), default=None, null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.title
class Meta:
verbose_name = 'Book'
verbose_name_plural = 'Books'
The first way to get all Books that are related to your active promotions is to extract the book ids from the queryset and pass it to a Book filter
active_promotions = Prommotion.objects.filter(active=True)
Book.objects.filter(id__in=active_promotions.values('book_id'))
Or simply filter books with active promotions by using the double underscore syntax to follow relationships
Book.objects.filter(prommotion__active=True).distinct()
I have two apps in Django project . one is "accounts" another is " Courses "
I have a model in accounts app
class Student(SoftDeleteModel):
user = models.OneToOneField(to=User, on_delete=models.CASCADE, related_name='student_info')
name = models.CharField(null=True, blank=True, max_length=250)
course_enrolled = models.ForeignKey(Courses,on_delete=models.CASCADE,blank=True)
trx_id = models.CharField(max_length=20)
date_of_birth = models.DateField(null=True, blank=True)
education_qualification = models.CharField(null=True, blank=True, max_length=250)
institution_name = models.CharField(null=True, blank=True, max_length=250)
image = models.ImageField(upload_to='photos/%y/%m/%d',null=True, blank=True)
address = models.CharField(null=True, blank=True, max_length=250)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.user.email
class Instractor(SoftDeleteModel):
user = models.OneToOneField(to=User, on_delete=models.CASCADE, related_name='instractor_info')
name = models.CharField(null=True, blank=True, max_length=250)
degination = models.CharField(null=True, blank=True, max_length=250)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.name
This is model for accounts
and Course Model is:
from accounts.models import *
class Courses(models.Model):
title = models.CharField(max_length=200,blank=True,null=True)
image = models.ImageField(null=True,upload_to="photos/course/")
category = models.ForeignKey(Category,on_delete=models.CASCADE)
instractor = models.ForeignKey(Instractor, on_delete=models.CASCADE,blank=True)
total_student_enrolled = models.IntegerField(null=True,blank=True)
price = models.IntegerField(blank=True,null=True)
course_length_in_hour = models.IntegerField(blank=True,null=True)
course_length_in_weeks = models.IntegerField(blank=True,null=True)
programming_language = models.CharField(max_length=500,null=True,blank=True)
course_requirements = models.TextField()
course_description = models.TextField()
what_you_will_learn = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateField(auto_now_add=True)
is_published = models.BooleanField(default=False)
slug = models.SlugField(null = False, blank = True)
def __str__(self):
return self.title
I have import courses.model but it showing that Instractor not Defined. But if i remove
course_enrolled = models.ForeignKey(Courses,on_delete=models.CASCADE,blank=True)
course_enrolled field from accounts model the error is not showing :/
I don't get what is the problem is .
Error Message is :
instractor = models.ForeignKey(Instractor, on_delete=models.CASCADE,blank=True)
NameError: name 'Instractor' is not define
You need to put the model name in quotes when defining a FK:
instractor = models.ForeignKey("accounts.Instractor", on_delete=models.CASCADE,blank=True)
I have the following 4 models in my program - User, Brand, Agency and Creator.
User is a superset of Brand, Agency and Creator.
A user can be a brand, agency or creator. They cannot take on more than one role. Their role is defined by the accountType property. If they are unset (i.e. 0) then no formal connection exists.
How do I express this in my model?
User model
class User(models.Model):
id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
email = models.EmailField(max_length=255, null=True, default=None)
password = models.CharField(max_length=255, null=True, default=None)
ACCOUNT_CHOICE_UNSET = 0
ACCOUNT_CHOICE_BRAND = 1
ACCOUNT_CHOICE_CREATOR = 2
ACCOUNT_CHOICE_AGENCY = 3
ACCOUNT_CHOICES = (
(ACCOUNT_CHOICE_UNSET, 'Unset'),
(ACCOUNT_CHOICE_BRAND, 'Brand'),
(ACCOUNT_CHOICE_CREATOR, 'Creator'),
(ACCOUNT_CHOICE_AGENCY, 'Agency'),
)
account_id = models.ForeignKey(Brand)
account_type = models.IntegerField(choices=ACCOUNT_CHOICES, default=ACCOUNT_CHOICE_UNSET)
class Meta:
verbose_name_plural = "Users"
def __str__(self):
return "%s" % self.email
Brand model
class Brand(models.Model):
id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
name = models.CharField(max_length=255, null=True, default=None)
brand = models.CharField(max_length=255, null=True, default=None)
email = models.EmailField(max_length=255, null=True, default=None)
phone = models.CharField(max_length=255, null=True, default=None)
website = models.CharField(max_length=255, null=True, default=None)
class Meta:
verbose_name_plural = "Brands"
def __str__(self):
return "%s" % self.brand
Creator model
class Creator(models.Model):
id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
first_name = models.CharField(max_length=255, null=True, default=None)
last_name = models.CharField(max_length=255, null=True, default=None)
email = models.EmailField(max_length=255, null=True, default=None)
youtube_channel_username = models.CharField(max_length=255, null=True, default=None)
youtube_channel_url = models.CharField(max_length=255, null=True, default=None)
youtube_channel_title = models.CharField(max_length=255, null=True, default=None)
youtube_channel_description = models.CharField(max_length=255, null=True, default=None)
photo = models.CharField(max_length=255, null=True, default=None)
youtube_channel_start_date = models.CharField(max_length=255, null=True, default=None)
keywords = models.CharField(max_length=255, null=True, default=None)
no_of_subscribers = models.IntegerField(default=0)
no_of_videos = models.IntegerField(default=0)
no_of_views = models.IntegerField(default=0)
no_of_likes = models.IntegerField(default=0)
no_of_dislikes = models.IntegerField(default=0)
location = models.CharField(max_length=255, null=True, default=None)
avg_views = models.IntegerField(default=0)
GENDER_CHOICE_UNSET = 0
GENDER_CHOICE_MALE = 1
GENDER_CHOICE_FEMALE = 2
GENDER_CHOICES = (
(GENDER_CHOICE_UNSET, 'Unset'),
(GENDER_CHOICE_MALE, 'Male'),
(GENDER_CHOICE_FEMALE, 'Female'),
)
gender = models.IntegerField(choices=GENDER_CHOICES, default=GENDER_CHOICE_UNSET)
class Meta:
verbose_name_plural = "Creators"
def __str__(self):
return "%s %s" % (self.first_name,self.last_name)
Agency model
class Agency(models.Model):
id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
name = models.CharField(max_length=255, null=True, default=None)
agency = models.CharField(max_length=255, null=True, default=None)
email = models.EmailField(max_length=255, null=True, default=None)
phone = models.CharField(max_length=255, null=True, default=None)
website = models.CharField(max_length=255, null=True, default=None)
class Meta:
verbose_name_plural = "Agencies"
def __str__(self):
return "%s" % self.agency
Update:
So I've whittled it down to this bit here in the model:
ACCOUNT_CHOICE_UNSET = 0
ACCOUNT_CHOICE_BRAND = 1
ACCOUNT_CHOICE_CREATOR = 2
ACCOUNT_CHOICE_AGENCY = 3
ACCOUNT_CHOICES = (
(ACCOUNT_CHOICE_UNSET, 'Unset'),
(ACCOUNT_CHOICE_BRAND, 'Brand'),
(ACCOUNT_CHOICE_CREATOR, 'Creator'),
(ACCOUNT_CHOICE_AGENCY, 'Agency'),
)
account_type = models.IntegerField(choices=ACCOUNT_CHOICES, default=ACCOUNT_CHOICE_UNSET)
limit = models.Q(app_label='api', model='Brand') | \
models.Q(app_label='api', model='Creator') | \
models.Q(app_label='api', model='Agency')
content_type = models.ForeignKey(ContentType, limit_choices_to=get_content_type_choices(), related_name='user_content_type')
content_object = GenericForeignKey('content_type', 'email')
If account_type = 1 then link to brand model
If account_type = 2 then link to creator model
If account_type = 3 then link to agency model
How do I accomplish this? Getting this error:
File "/Users/projects/adsoma-api/api/models.py", line 7, in <module>
class User(models.Model):
File "/Users/projects/adsoma-api/api/models.py", line 28, in User
content_type = models.ForeignKey(ContentType, limit_choices_to=get_content_type_choices(), related_name='user_content_type')
NameError: name 'get_content_type_choices' is not defined
Have you tried exploring Django's GenericForeignKey field?
class User(models.Model):
...
limit = models.Q(app_label='your_app_label', model='brand') |
models.Q(app_label='your_app_label', model='creator') |
models.Q(app_label='your_app_label', model='agency')
content_type = models.ForeignKey(ContentType, limit_choices_to=limit, related_name='user_content_type')
object_id = models.UUIDField()
content_object = GenericForeignKey('content_type', 'object_id')
You can access the User's brand/creator/agency by using the following notation:
User.objects.get(pk=1).content_object
This will be an instance of Brand/Creator/Agency as per the content_type.
https://docs.djangoproject.com/en/stable/ref/contrib/contenttypes/#django.contrib.contenttypes.fields.GenericForeignKey
Update based on your comment
Re 1: Using email:
class User(models.Model):
...
email = models.EmailField(max_length=255, unique=True)
limit = models.Q(app_label='your_app_label', model='brand') |
models.Q(app_label='your_app_label', model='creator') |
models.Q(app_label='your_app_label', model='agency')
content_type = models.ForeignKey(ContentType, limit_choices_to=get_content_type_choices, related_name='user_content_type')
content_object = GenericForeignKey('content_type', 'email')
Note: Email can not be a nullable field anywhere if you follow this approach! Also this approach seems hacky/wrong since the email field is now declared in multiple places; and the value can change if you re-assign the content objects. It is much cleaner to link the GenericForeignKey using the discrete UUIDField on each of the other three models
Re 2: Using account_type field:
ContentType is expected to be a reference to a Django Model; therefore it requires choices that are Models and not integers.
The function of limit_choices_to is to perform a filtering such that all possible models are not surfaced as potential GenericForeignKey
class ContentType(models.Model):
app_label = models.CharField(max_length=100)
model = models.CharField(_('python model class name'), max_length=100)
objects = ContentTypeManager()
However, limit_choices_to does accept callables; so you can write a helper method that translates your account_type to the correct Model
I am not clear about how this transaltion should work; so I leave that to you.
Here is how I solve it, override the save method check your condition
tested on Django 3.2
CUSTOMER = [
('customer', 'customer'),
('supplier', 'supplier'),
]
class Customer(models.Model):
name = models.CharField(max_length=256, null=False, blank=False)
user_type = models.CharField(max_length=32, choices=CUSTOMER)
class SupplierOrder(models.Model):
price = models.FloatField(default=0)
supplier = models.ForeignKey(Customer, related_name='supplier', on_delete=models.CASCADE)
def save(self, *args, **kwargs):
supplier = get_object_or_404(Customer, id=self.supplier.id)
if supplier.user_type != 'supplier':
raise ValueError('selected user must be supplier')
super().save(*args, **kwargs)
I am trying to get user's gender who is in room between start_date and end_date range here is models.py
class Profile(models.Model):
MALE = 'M'
FEMALE = 'F'
GENDER_CHOICES = (
(MALE, u'ere'),
(FEMALE, u'eme')
)
FOOD_TYPE = (
('Veg', 'Vegeterian'),
('Green', 'Green')
)
user = models.OneToOneField(User, related_name="profile", null=True)
firstname = models.CharField(max_length=50, null=True)
lastname = models.CharField(max_length=50, null=True)
phone1 = models.CharField(max_length=50, null=True)
phone2 = models.CharField(max_length=50, null=True, blank=True)
birthdate = models.DateField(blank=True, null=True)
gender = models.CharField(max_length=10, choices=GENDER_CHOICES, null=True)
emd_number = models.CharField(max_length=10, null=True)
special_situation = models.IntegerField(choices=SITUATION_CHOICES, null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
email = models.EmailField(blank=True, null=True)
city = models.CharField(max_length=20, blank=True)
food_type = models.CharField(max_length=50, choices=FOOD_TYPE, blank=True)
def __unicode__(self):
return self.user.username
class Room(models.Model):
number = models.CharField(max_length=8, null=True)
category = models.ForeignKey(RoomCategory, related_name="rooms")
beds = models.PositiveIntegerField(null=True)
description = models.TextField(blank=True)
size = models.CharField(max_length=2, blank=True)
def __unicode__(self):
return self.number
class Reservation(models.Model):
created_at = models.DateTimeField(auto_now_add=True, editable=False)
transport_type = models.CharField(max_length=8, blank=True)
start_date = models.DateField(null=True)
end_date = models.DateField(null=True)
total_days = models.PositiveIntegerField(null=True, blank=True)
arrival_date = models.DateField(null=True, blank=True)
user = models.ForeignKey(User, related_name="customers")
room = models.ForeignKey(Room, related_name="reservations")
total_payment = models.PositiveIntegerField(null=True, blank=True)
total_paid = models.PositiveIntegerField(null=True, blank=True)
currently i get the rooms by this query below:
queryset = Room.objects.all()
if start_date && end_date:
queryset = queryset.exclude(reservations__start_date__range=[start_date, end_date], reservations__end_date__range=[start_date, end_date])
how to get user's gender who is in room between dates
You can check like,
for reservetion in Reservation.objects.filter(room__in=queryset):
print reservation.user.gender
#Adaikalaraj how to append user gender in get_queryset method?
class RoomList(ListAPIView):
""" Listing all room """
serializer_class = RoomSerializer
def get_queryset(self):
queryset = Room.objects.all()
start_date = self.request.query_params.get('start_date', None) #date string
end_date = self.request.query_params.get('end_date', None) #date string
if start_date and end_date:
queryset = queryset.exclude(reservations__start_date__range=[start_date, end_date], reservations__end_date__range=[start_date, end_date])
return queryset