Maintaining multiple instance of the same object in Django models - django

I am creating a small app in Django where I need to maintain details of training batches of different courses. Each of these batches will have a list of topics to be covered. For e.g, A python course could be conducted by different trainers in different colleges at the same time and so they both will have their own list of topics. Following is what I have come up with but think I am wrong. I am confused about how to go about it. Kindly suggest the right approaches.
My Models so far,
class Course(models.Model):
name = models.CharField(max_length=50, default="Enter Course Name")
class Trainer(models.Model):
name = models.CharField(max_length=50, default="Enter Trainer Name")
class College(models.Model):
name = models.CharField(max_length=50, default="Enter College Name")
class CourseBatch(models.Model):
startDate = models.DateField(null = True, blank = True)
endDate = models.DateField(null = True, blank = True)
batchName = models.CharField(max_length=50, default="Enter Batch Name")
course = models.ForeignKey(Course, on_delete=models.CASCADE, related_name="course")
trainer = models.ForeignKey(Trainer, on_delete=models.CASCADE, related_name="trainer")
college = models.ForeignKey(College, on_delete=models.CASCADE, related_name="college")
class CheckPoints(models.Model):
description = models.CharField(max_length=50, default="Enter Description")
chkPoint = models.BooleanField(default=False)
course = models.ForeignKey(Course, on_delete=models.CASCADE, related_name="course")
class ChkListForBatch(models.Model):
batch = models.ForeignKey(CourseBatch, on_delete=models.CASCADE, related_name="coursebatch")
chkpoint = models.ForeignKey(CheckPoints, on_delete=models.CASCADE, related_name="chkpoint")
Here every CourseBatch needs to have its own set of CheckPoints (topics) to be covered. How can I implement the same?

As i understand it, you have a list of checkpoints to each cource. And you want to choose, which checkpoints will be for each particular batch.
Updated. If you want to save the completed control point or not, do this:
class Course(models.Model):
name = models.CharField(max_length=50, default="Enter Course Name")
class Trainer(models.Model):
name = models.CharField(max_length=50, default="Enter Trainer Name")
class College(models.Model):
name = models.CharField(max_length=50, default="Enter College Name")
class CourseBatch(models.Model):
startDate = models.DateField(null = True, blank = True)
endDate = models.DateField(null = True, blank = True)
batchName = models.CharField(max_length=50, default="Enter Batch Name")
course = models.ForeignKey(Course, on_delete=models.CASCADE, related_name="course")
trainer = models.ForeignKey(Trainer, on_delete=models.CASCADE, related_name="trainer")
college = models.ForeignKey(College, on_delete=models.CASCADE, related_name="college")
class CheckPoints(models.Model):
description = models.CharField(max_length=50, default="Enter Description")
course = models.ForeignKey(Course, on_delete=models.CASCADE, related_name="course")
class ChkListForBatch(models.Model):
batch = models.ForeignKey(CourseBatch, on_delete=models.CASCADE, related_name="coursebatch")
checkpoint = models.ForeignKey(CheckPoints, on_delete=models.CASCADE, related_name="chkpoint")
checkpoint_is_done = models.BooleanField(default=False)

class Course(models.Model):
name = models.CharField(max_length=50, default="Enter Course Name")
class Trainer(models.Model):
name = models.CharField(max_length=50, default="Enter Trainer Name")
class College(models.Model):
name = models.CharField(max_length=50, default="Enter College Name")
class CourseBatch(models.Model):
startDate = models.DateField(null = True, blank = True)
endDate = models.DateField(null = True, blank = True)
batchName = models.CharField(max_length=50, default="Enter Batch Name")
course = models.ForeignKey(Course, on_delete=models.CASCADE, related_name="course")
trainer = models.ForeignKey(Trainer, on_delete=models.CASCADE, related_name="trainer")
college = models.ForeignKey(College, on_delete=models.CASCADE, related_name="college")
class CheckPoints(models.Model):
description = models.CharField(max_length=50, default="Enter Description")
chkPoint = models.BooleanField(default=False)
course = models.ForeignKey(Course, on_delete=models.CASCADE, related_name="course")
course_batch = models.ForeignKey(to=CourseBatch, on_delete=models.CASCADE) # This means that you have multiple checkpoints associated with single coursebatch.
course_batch_m2m = models.ManyToManyField(to=CourseBatch) # This will create intermediate model, with columns checkpoints_id | coursebatch_id. This means multiple checkpoints has multiple coursebatch and vice-versa.
class ChkListForBatch(models.Model):
batch = models.ForeignKey(CourseBatch, on_delete=models.CASCADE, related_name="coursebatch")
chkpoint = models.ForeignKey(CheckPoints, on_delete=models.CASCADE, related_name="chkpoint")
Check CheckPoints model, I added ForeignKey and ManyToManyField with explanaitans.

Related

How to use django-autocomplete-light and django-hacker to make a chained dropdown in django admin?

I have 3 models 1) university 2) courses and 3) enquiry.
My enquiry model has a foreign key to "course". And Course has a foreign key to the university. I only want to show the courses related to that university while adding an enquiry. I tried django-smart-select but failed to do so. I tried This answer but I dont understand the logic and failed to implement in my project.
this is my models.py file
class university(models.Model):
univ_name = models.CharField(max_length=100)
country = CountryField(blank=True, null=True)
univ_desc = models.CharField(max_length=1000)
univ_logo = models.ImageField(upload_to="media")
univ_phone = models.CharField(max_length=10, blank=True)
univ_email = models.EmailField(max_length=254, blank=True)
univ_website = models.URLField(blank=True)
assigned_users = models.ForeignKey(get_user_model(), on_delete=models.CASCADE, default="")
def __str__(self):
return self.univ_name
class Meta:
verbose_name_plural = "Universities"
class Course(models.Model):
university = models.ForeignKey(university, on_delete=models.CASCADE)
course_name = models.CharField(max_length=100)
course_levels = models.ForeignKey(course_levels, on_delete=models.CASCADE)
intake = models.ForeignKey(intake, on_delete=models.CASCADE)
documents_required = models.ForeignKey(documents_required, on_delete=models.CASCADE)
course_requirements = models.ForeignKey(course_requirements, on_delete=models.CASCADE)
Active = models.BooleanField()
def __str__(self):
return self.course_name
class enquiry(models.Model):
student_name = models.CharField(max_length=100)
student_phone = models.CharField(max_length=10)
student_email = models.EmailField()
student_address = models.TextField()
current_education = models.ForeignKey(current_education, on_delete=models.CASCADE)
country_interested = CountryField(blank=True, null=True)
university_interested = models.ForeignKey(university, on_delete=models.CASCADE)
course_interested = models.ForeignKey(Course, on_delete=models.CASCADE, limit_choices_to={'Active':True})
level_applying_for = models.ForeignKey(course_levels, on_delete=models.CASCADE)
intake_interested = models.ForeignKey(intake, on_delete=models.CASCADE)
assigned_users = models.ForeignKey(User, on_delete=models.CASCADE, default="", limit_choices_to={"is_active": True})
enquiry_status = models.ForeignKey(enquiry_status, on_delete=models.CASCADE, default="")
course_interested= ChainedForeignKey(Course,chained_field= 'university_interested',chained_model_field= 'university',show_all= False,auto_choose= True,sort=True,limit_choices_to = {"Active": True},)
I want to show the course_interested field related to that university. Need help.
I tried using django-smart-select but failed to implement it. I am not aware of jquery and ajax so that is out of the question to use in my project.
got the solution I used the django-select2 and was able to solve this issue.

How to add ArrayField in Django?

my models.py
class LiveClass_details(models.Model):
standard = models.ForeignKey(LiveClass, on_delete=models.CASCADE)
chapter_details = models.TextField(default='')
mentor_id = models.ForeignKey(Mentor, max_length=30, on_delete=models.CASCADE)
start_time = models.DateTimeField()
end_time = models.DateTimeField()
doubtClass = models.OneToOneField(DoubtClasses, on_delete=models.PROTECT, null=True, blank=True)
isDraft = models.BooleanField(default=True)
ratings = models.FloatField(default=0)
no_of_students_registered = models.IntegerField(default=0)
# registered_students = models.ManyToManyField(RegisteredNames, null=True, blank=True)
no_of_students_attended = models.IntegerField(default=0)
class Meta:
verbose_name_plural = 'LiveClass_details'
class RegisteredNames(models.Model):
name = models.CharField(max_length=100, unique=True)
liveclass_id = models.ForeignKey
I am creating a endpoint where when a user register himself his name will get added to registered_students , so i had made a registered students ManyToMany Field hoping it will get updated when a user is registered but then i understand that it will contain all the names that are present in the RegisteredNames Model meaning names registered across all the liveclasses but i want only the names that are registered for a particular liveclass in the field so i need a array like field which i think is not possible so please help me in improving my logic, how can i achieve it
The documentation and django tutorials are very good: https://docs.djangoproject.com/en/3.2/topics/db/models/ https://docs.djangoproject.com/en/3.2/intro/tutorial02/#creating-models
Your code is very close. You don’t need the many-to-many field, and you need to specify the type of the Foreign key relationship in the RegisteredNames. You can do this:
class LiveClass_details(models.Model):
standard = models.ForeignKey(LiveClass, on_delete=models.CASCADE)
chapter_details = models.TextField(default='')
mentor_id = models.ForeignKey(Mentor, max_length=30, on_delete=models.CASCADE)
start_time = models.DateTimeField()
end_time = models.DateTimeField()
doubtClass = models.OneToOneField(DoubtClasses, on_delete=models.PROTECT, null=True, blank=True)
isDraft = models.BooleanField(default=True)
ratings = models.FloatField(default=0)
no_of_students_attended = models.IntegerField(default=0)
class Meta:
verbose_name_plural = 'LiveClass_details'
class RegisteredNames(models.Model):
name = models.CharField(max_length=100, unique=True)
liveclass = models.ForeignKey(LiveClass_details, on_delete=Models.CASCADE)
Then, simply:
name = RegisteredNames.objects.create(name="Dhruv", liveclass_id=1)
To get all the registered names from a liveclass_details:
names = LiveClass_details.objects.get(id=1).registerednames_set.all()
num_reg = len(names)

Django Query across multiple tables

I can use some help on a query using 3 tables. Here is what my models contains.
class VolunteerRecord(models.Model):
eventname = models.CharField(help_text=_('Name of the event'),max_length=256, blank=False, default='')
category = models.CharField(max_length=256, blank=False, choices=CATEGORY_CHOICES)
hours = models.FloatField(blank=False)
date=models.DateField(help_text=_('Enter the date of the event'),validators=MaxValueValidator(limit_value=date.today)])
mileage = models.FloatField(blank=True, null=True)
owner = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True)
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
streetaddress1 = models.CharField(blank=True, max_length=256)
streetaddress2 = models.CharField(blank=True, max_length=256)
city = models.CharField(blank=True, max_length=30)
state = models.CharField(max_length=256, blank=False, choices=US_STATES)
zipcode = models.CharField(blank=True, max_length=15)
county = models.CharField(max_length=256, blank=False, choices=STATE_COUNTIES)
I would like to filter all VolunteerRecords where the owner's county = request.user's county
So far I have... (not sure what I am suppose to put where my ??? are)
def history(request):
current_user_county = request.user.profile.county
records = VolunteerRecord.objects.filter(????=current_user_county)
I was able to figure it our with your help.
records = VolunteerRecord.objects.filter(owner__profile__county=request.user.profile.county)

How to get the minimum value of an instance of django model

I am trying to get the minimum or the lowest value of a model field in django model. The field is room_Price. I am therefore trying to get the minimum of value of this field for each instance of a model. My model are as as follows
class Hotels(models.Model):
name = models.CharField(max_length=255)
address = models.CharField(max_length=255)
city = models.CharField(max_length=255)
country = models.CharField(max_length=255)
mobile_number = models.CharField(max_length=12)
created_at = models.DateTimeField(default=timezone.now)
last_modified = models.DateTimeField(auto_now=True)
description = models.TextField()
slug = models.SlugField(unique=True)
property_photo = models.ImageField(default='default.jpg', upload_to='hotel_photos')
star_rating = models.PositiveIntegerField()
contact_person = models.ForeignKey(UserProfile, on_delete = models.CASCADE, null=True, blank=True,)
class Room(models.Model):
hotel = models.ForeignKey(Hotels,on_delete = models.CASCADE, null=True, blank=True,)
room_photo = models.ImageField(default='default.jpg', upload_to='room_photos')
room_Name = models.CharField(max_length = 200)
room_details = models.CharField(max_length = 500)
room_Capacity = models.PositiveIntegerField(default = 0)
slug = models.SlugField(unique=True)
# guest_numbers = models.IntegerField(default=0)
room_Price= models.PositiveIntegerField(default = 0)
total_Rooms = models.PositiveIntegerField(default=0)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
user = models.ForeignKey(UserProfile, on_delete=models.CASCADE, null=True, blank=True,)
More details
From the above models, a hotel can have as many rooms as possible. Now i want to fetch the lowest priced room for each hotel. I tried to use Hotels.objects.aggregate(min_price=Min('room__room_Price')) but it is fetching the overall minimum price of all the hotel rooms. Kindly assist
You can try to add ordering to your model and then find lowest price in a loop:
class Room(models.Model):
...
class Meta:
ordering = ['room_Price']
And filter in views:
lowest_prices = {}
for i in Hotels.objects.all():
price = Room.objects.filter(hotel=i.id)[0].room_Price
lowest_prices[i.name] = price
print(lowest_prices)
I put prices in a dict, but you can do anything you want with it.

Django forms with grid layout

I am trying to implement a grid layout for entering marks of students into my model. The model is described as:
class User(AbstractUser):
is_student = models.BooleanField(default=False)
is_teacher = models.BooleanField(default=True)
email = models.EmailField('email address', blank=False)
first_name = models.CharField(max_length=50, blank=False)
last_name = models.CharField(max_length=50, blank=False)
class Student(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, null=True, related_name='student_profile')
yoe = models.IntegerField('year of enrollment', choices=YEAR_CHOICES,
default=datetime.datetime.now().year)
photo = models.ImageField(upload_to='student/%Y/')
class Paper(models.Model):
semester = models.CharField(max_length=1)
name_of_paper = models.CharField(max_length=200)
max_pass_marks = models.IntegerField("Max Marks",validators=[MaxValueValidator(99)])
class Test(models.Model):
student = models.ForeignKey(Student, on_delete=models.CASCADE, default='')
paper = models.ForeignKey(Paper, on_delete=models.CASCADE, default='')
dot = models.DateField("Date of Test")
marks = models.IntegerField("Marks Obtained",validators=[MaxValueValidator(99)], default=0)
I want to be able to create a form with a grid layout where each row of the grid will have the students name followed by text boxes where users can enter the test scores obtained by students in each of the 'Paper' they have opted for. Obviously the test scores should then populate the 'Test' table/model. I am relatively new to django and cant really wrap my head around this. Any help will be appreciated.