I am trying to create an educational website using django, so I have two models class and course which have a one-to-many foreignkey relationship between them i.e. one course can have several class but one class can only have one course. But this creates a problem for me. That is, in my course_detail_view I have assigned the model course. So I cannot render classes in my html file. Can anyone help me solve this ?
My models.py:
class Course(models.Model):
title = models.CharField(max_length=100)
image = models.ImageField(upload_to='class/instructor_pics', null=True)
instructor = models.CharField(max_length=100)
instructor_image = models.ImageField(upload_to='class/instructor_pics', null=True)
students = models.ManyToManyField(User, related_name='courses_joined', blank=True)
slug = models.SlugField(max_length=200, unique=True)
description = models.TextField(max_length=300, null=True)
created = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ['-created']
def __str__(self):
return self.title
class Class(models.Model):
title = models.CharField(max_length=100)
video = models.FileField(upload_to='class/class_videos',null=True,
validators=[FileExtensionValidator(allowed_extensions=['MOV','avi','mp4','webm','mkv'])])
course = models.ForeignKey(Course, on_delete=models.CASCADE, null=True, related_name='classes')
def __str__(self):
return self.title
My views.py:
class CourseDetailView(LoginRequiredMixin, DetailView):
model = Course
template_name = 'class/course.html'
Thanks in advance!
Related
I am trying to create an educational website using django so I have a class model and a course model. I have tried to use the Many-to-one foreignkey relationship but that doesn't work, I can create classes using foreignkey but that class is not being assigned to that course only. It appears in other courses as well. So how can I make this work? What should I change?
My models.py:
class Class(models.Model):
title = models.CharField(max_length=100)
video = models.FileField(upload_to='class/class_videos',null=True,
validators=[FileExtensionValidator(allowed_extensions=['MOV','avi','mp4','webm','mkv'])])
def __str__(self):
return self.title
class Course(models.Model):
title = models.CharField(max_length=100)
image = models.ImageField(upload_to='class/instructor_pics', null=True)
instructor = models.CharField(max_length=100)
instructor_image = models.ImageField(upload_to='class/instructor_pics', null=True)
students = models.ManyToManyField(User, related_name='courses_joined', blank=True)
classes = models.ForeignKey(Class, on_delete=models.CASCADE, null=True)
slug = models.SlugField(max_length=200, unique=True)
description = models.TextField(max_length=300, null=True)
created = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ['-created']
def __str__(self):
return self.title
You are using the foreign key in the wrong model. If each class can only have one course, but a single course, can have multiple classes, you should place the ForeignKey in the class model instead of the course model. Your code would be like this:
class Course(models.Model):
title = models.CharField(max_length=100)
image = models.ImageField(upload_to='class/instructor_pics', null=True)
instructor = models.CharField(max_length=100)
instructor_image = models.ImageField(upload_to='class/instructor_pics', null=True)
students = models.ManyToManyField(User, related_name='courses_joined', blank=True)
slug = models.SlugField(max_length=200, unique=True)
description = models.TextField(max_length=300, null=True)
created = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ['-created']
def __str__(self):
return self.title
class Class(models.Model):
title = models.CharField(max_length=100)
video = models.FileField(upload_to='class/class_videos',null=True,
validators=[FileExtensionValidator(allowed_extensions=['MOV','avi','mp4','webm','mkv'])])
course = models.ForeignKey(Course, on_delete=models.CASCADE, null=True, related_name='classes')
def __str__(self):
return self.title
And when you want to list the classes of a single course, you can use this code (you should use the related_name field in the source model like the way I have used in the class model):
course = Course.objects.filter(some_filter=some_value).first()
course.classes.first() # This will return the first class of the course
Basically I am creating a website using django where I have created a class called courses and a separate class Class. I'm now confused which relationship I should use.
My code:
class Class(models.Model):
title = models.CharField(max_length=100)
video = models.FileField(upload_to='class/class_videos',null=True,
validators=[FileExtensionValidator(allowed_extensions=['MOV','avi','mp4','webm','mkv'])])
def __str__(self):
return self.name
class Course(models.Model):
title = models.CharField(max_length=100)
image = models.ImageField(upload_to='class/instructor_pics', null=True)
instructor = models.CharField(max_length=100)
instructor_image = models.ImageField(upload_to='class/instructor_pics', null=True)
students = models.ManyToManyField(User, related_name='courses_joined', blank=True)
slug = models.SlugField(max_length=200, unique=True)
description = models.TextField(max_length=300, null=True)
created = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ['-created']
def __str__(self):
return self.title
Thanks in advance!
Change your code to
class Course(models.Model):
title = models.CharField(max_length=100)
image = models.ImageField(upload_to='class/instructor_pics', null=True)
instructor = models.CharField(max_length=100)
instructor_image = models.ImageField(upload_to='class/instructor_pics', null=True)
enrolled_students = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='enrolled_students', blank=True)
students = models.ManyToManyField(User, related_name='courses_joined', blank=True)
slug = models.SlugField(max_length=200, unique=True)
description = models.TextField(max_length=300, null=True)
created = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ['-created']
def __str__(self):
return self.title
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
img = Image.open(self.image.path)
if img.height > 285 or img.width > 201:
output_size = (285, 201)
img.thumbnail(output_size)
img.save(self.image.path)
img2 = Image.open(self.instructor_image.path)
if img2.height > 40 or img2.width > 40:
output_size = (40, 40)
img2.thumbnail(output_size)
img2.save(self.instructor_image.path)
class Class(models.Model):
title = models.CharField(max_length=100)
video = models.FileField(upload_to='class/class_videos',null=True,
validators=[FileExtensionValidator(allowed_extensions=['MOV','avi','mp4','webm','mkv'])])
course = models.ForeignKey(Course, on_delete=models.CASCADE, null=True, related_name='classes')
def __str__(self):
return self.title
Thinking about your problem, each Class can only belong to one course, but each course can have multiple classes correct?
If that's the case then you should have a many to one where many is the class and the course is the one.
You already have it somewhat in your code
students = models.ManyToManyField(User, related_name='courses_joined', blank=True)
classes = models.OneToManyField(Class, related_name='...')
I reckon that the course will be divided into classes. So, the Class model will contain a ForeignKey field that points to the Course model.
More precisely, this is what OP will want
class Class(models.Model):
course = models.ForeignKey(Course, related_name='classes', on_delete=models.CASCADE)
I'm new to django (and python) and I have a question.
I have this model:
class Material(models.Model):
name = models.CharField(max_length=256, blank=True)
description = models.TextField(null=True, blank=True)
def __str__(self):
return self.name
class Meta:
abstract = True
and
class Experiments(models.Model):
title = models.CharField(max_length=200)
experiment = models.TextField(null=True, blank=True)
def __str__(self):
return self.title
I want to query it so I have only have the Materials used in the Experiments model. I was reading about Q objects but I'm not sure how to use it. I appreciate any help!
I am new to Django (and databases for that matter) and trying to create a simple inventory application to help learn. I've been through the tutorials and am going through some books, but I am stuck at what i think is simple, just not sure where to look or how to ask.
With an inventory application, you have your equipment which then has a manufacturer, which the equipment has a model number that only that manufacturer has. Lets say Dell Optiplex 3040. I am also using the admin console right now as well. So i would like to be able to relate equipment to a manufacturer and then also relate the equipment to the model number. It almost seems as I am needing to use the many to many field and the through field to accomplish what I am trying to do but I dont think that is the right way to do it (shown in the link below). https://docs.djangoproject.com/en/1.9/topics/db/models/#many-to-many-relationships
Below is the code I have so far. Thank you.
from django.db import models
# Create your models here.
class Department(models.Model):
department = models.CharField(max_length=50)
def __str__(self):
return self.department
class Manufacturer(models.Model):
manufacturer = models.CharField(max_length=50)
def __str__(self):
return self.manufacturer
class EquipmentModel(models.Model):
equipmentModel = models.CharField(max_length=50)
def __str__(self):
return self.equipmentModel
class Employees(models.Model):
employee_name_first = models.CharField(max_length=25)
employee_name_last = models.CharField(max_length=25)
employee_username = models.CharField(max_length=20)
phone = models.IntegerField()
assigned_equipment = models.ForeignKey('Device', default='undefined')
department = models.ForeignKey('Department', on_delete=models.CASCADE, default='undefined')
job_title = models.ManyToManyField('Job_Positions', default='undefined')
def __str__(self):
return self.employee_username
class Device(models.Model):
ip = models.GenericIPAddressField(protocol='IPv4',unpack_ipv4=False,null=True, blank=True)#might be good to seperate IP in its own class because a device can have multiple IP's
department = models.ForeignKey('Department', on_delete=models.CASCADE)
manufacturer = models.ForeignKey('Manufacturer', on_delete=models.CASCADE)
serial_number = models.CharField(max_length=50)
date_created = models.DateTimeField(auto_now=False, auto_now_add=True)
date_updated = models.DateTimeField(auto_now=True, auto_now_add=False)
comments = models.TextField(blank=True)
def __str__(self):
return self.serial_number
class Job_Positions(models.Model):
position_title = models.CharField(max_length=50)
position_description = models.TextField(blank=True)
def __str__(self):
return position_title
***Edit to add the updated code and the admin.py code in response question I had to answer.
#admin.py
from django.contrib import admin
# Register your models here.
from .models import Device,Department,Manufacturer,Employees, Job_Positions, EquipmentModel
class DeviceModelAdmin(admin.ModelAdmin):
list_display = ["ip", "department","model","serial_number","date_updated"]
list_filter = ["department","model","ip"]
search_fields = ["ip"]
class Meta:
model = Device
class EmployeesModelAdmin(admin.ModelAdmin):
list_display = ["employee_name_first", "employee_name_last", "employee_username", "phone"]
list_filter = ["department"]
class Meta:
model = Employees
admin.site.register(Device, DeviceModelAdmin)
admin.site.register(Department)
admin.site.register(Manufacturer)
admin.site.register(EquipmentModel)
admin.site.register(Employees, EmployeesModelAdmin)
admin.site.register(Job_Positions)
updated models.py
from django.db import models
# Create your models here.
class Department(models.Model):
department = models.CharField(max_length=50)
def __str__(self):
return self.department
class Manufacturer(models.Model):
manufacturer = models.CharField(max_length=50)
def __str__(self):
return self.manufacturer
class EquipmentModel(models.Model):
model_number = models.CharField(max_length=50)
manufacturer = models.ForeignKey('Manufacturer', on_delete=models.CASCADE)
def __str__(self):
return self.model_number
class Employees(models.Model):
employee_name_first = models.CharField(max_length=25)
employee_name_last = models.CharField(max_length=25)
employee_username = models.CharField(max_length=20)
phone = models.IntegerField()
assigned_equipment = models.ForeignKey('Device', default='undefined')
department = models.ForeignKey('Department', on_delete=models.CASCADE, default='undefined')
job_title = models.ManyToManyField('Job_Positions', default='undefined')
def __str__(self):
return self.employee_username
class Device(models.Model):
ip = models.GenericIPAddressField(protocol='IPv4',unpack_ipv4=False,null=True, blank=True)#might be good to seperate IP in its own class because a device can have multiple IP's
department = models.ForeignKey('Department', on_delete=models.CASCADE)
model = models.ForeignKey('EquipmentModel', on_delete=models.CASCADE,null=True)
serial_number = models.CharField(max_length=50)
date_created = models.DateTimeField(auto_now=False, auto_now_add=True)
date_updated = models.DateTimeField(auto_now=True, auto_now_add=False)
comments = models.TextField(blank=True)
def __str__(self):
return self.serial_number
class Job_Positions(models.Model):
position_title = models.CharField(max_length=50)
position_description = models.TextField(blank=True)
def __str__(self):
return position_title
A many-to-many relationship is not what you want here, because any piece of equipment (I assume) can only have one manufacturer.
You do need an intermediate model which stores the model information, and you already have one in your EquipmentModel. I would suggest modifying it as follows:
class EquipmentModel(models.Model):
# This stores information about a particular model of device
manufacturer = models.ForeignKey('Manufacturer', on_delete=models.CASCADE)
model_number = models.CharField(max_length=50)
And then instead of having a foreign key to the manufacturer in Device, replace it with a foreign key to the equipment model:
class Device(models.Model):
# ...
model = models.ForeignKey('EquipmentModel', on_delete=models.CASCADE)
I am a django newbie and have one more big struggle for longer time... :/
User can choose a 'main language' which is set as ForeignKey. User can choose 'further languages' as ManyToMany (Checkbox). Assuming, user selects english as 'main' language, so english has to be filterd out from the 'further languages'... have been searching so much and have no idea how to do it. Is this even possible without JavaScript?
Of course, I could set the 'queryset' in the second form but it would filter the objects after the submit... The similar problem is, when a selected country has to be connected to the proper zipcodes...
I am very thankful for any hints.
Best regards.
class Country(models.Model):
enter code here
country = models.CharField(max_length=40)
active = models.BooleanField(default=True)
class Meta:
verbose_name_plural = 'Länder'
def __str__(self):
return self.country
class ZipCode(models.Model):
zipcode = models.CharField(max_length=5)
city = models.CharField(max_length=255)
active = models.BooleanField(default=False)
class Meta:
verbose_name_plural = 'Postleitzahlen'
def __str__(self):
return '{0} {1}'.format(self.zipcode, self.city)
class MainLanguage(models.Model):
language = models.CharField(verbose_name='Hauptsprache', max_length=40)
active = models.BooleanField(default=True)
class Meta:
verbose_name_plural = 'Hauptsprachen'
ordering = ['language']
def __str__(self):
return self.language
class SecondLanguage(models.Model):
language = models.CharField(verbose_name='weitere Sprachen', max_length=40)
active = models.BooleanField(default=False)
class Meta:
verbose_name_plural = 'weitere Sprachen'
ordering = ['language']
def __str__(self):
return self.language
class CustomUserprofile(models.Model):
user = models.OneToOneField(User)
name = models.CharField(verbose_name='Vorname', max_length=40,
null=True, blank=True)
country = models.ForeignKey(Country, verbose_name='Land',
null=True, blank=True)
zipcode = models.ForeignKey(ZipCode, blank=True, null=True)
main_language = models.ForeignKey(
MainLanguage, verbose_name='Hauptsprache',
null=True, blank=True)
second_language = models.ManyToManyField(
SecondLanguage, verbose_name='weitere Sprachen',
null=True, blank=True)
class UserProfileForm(forms.ModelForm):
second_language = forms.ModelMultipleChoiceField(
queryset=SecondLanguage.objects.all(),
required=False,
widget=forms.CheckboxSelectMultiple)
class Meta:
model = CustomUserprofile
exclude = ('user',)