I have a question about how to properly model my data in Django (and later in graphene).
I have a model exam which consists of date, subject, participants, results where subject,participants, results are references to other objects. I could of course have two lists of participants and results however it would be practical to have a map of type:
pseudocode:
results= map(participant,result)
To be honest I do not know if this is even possible without introducing a additional model object participant_results
Any insight very welcome.
Benedict
I would model it this way:
class Exam(models.Model):
date = models.DateField()
subject = models.TextField()
class Participant(models.Model):
person = models.ForeignKey(Person, on_delete=models.PROTECT, related_name="participants")
result = models.FloatField(null=True, blank=True)
exam = models.ForeignKey(Exam, on_delete=models.PROTECT)
class Person(models.Model):
name = ...
You retrieve all participant from an exam using
exam.participants
Related
I have 3 models (supervisor, students, and allocation)
I am building an allocation system where multiple students can be allocated to one supervisor
Now I want my model to be able to yeld this output
Example of how i want the output to come out
Here are the structure of my model
class StudentProfile(models.Model):
stud_id = models.UUIDField(default=uuid.uuid4, primary_key=True, unique=True)
user_id = models.OneToOneField(User,blank=True, null=True, on_delete=models.CASCADE)
programme_id = models.ForeignKey(Programme, on_delete=models.CASCADE)
session_id = models.ForeignKey(Sessi`**enter code here**`on, on_delete=models.CASCADE)
type_id = models.ForeignKey(StudentType, on_delete=models.CASCADE)
dept_id = models.ForeignKey(Department, on_delete=models.CASCADE)
class SupervisorProfile(models.Model):
super_id = models.UUIDField(default=uuid.uuid4, primary_key=True, unique=True)
user_id = models.ForeignKey(User, on_delete=models.CASCADE)
dept_id = models.ForeignKey(Department, on_delete=models.CASCADE)
class Allocate(models.Model):
allocate_id = models.UUIDField(default=uuid.uuid4, primary_key=True, unique=True)
stud_id = models.ForeignKey(StudentProfile, on_delete=models.CASCADE)
super_id = models.ForeignKey(SupervisorProfile, on_delete=models.CASCADE)
now my main focus is the Allocate model where the allocation is made, and there is a lot of redundancy any suggestions on how to improve my model to remove redundancy in yielding the expected HTML output would be appreciated 🙏
As far as I understand, you need to assign several students to one Supervisor
For this, you only need to use ForeignKey in class StudentProfile
As below:
supervisor=models.ForeignKey(Supervisor,on_delete=models.DO_NOTHING)
But if you need to connect a student to several Supervisor, you should use ManyToManyField
ManyToManyField automatically creates a third table like class Allocate of yourself
For more information, refer to the hire.
It is also possible to reduce the redundancy by considering the department.
However
It doesn't seem that less redundancy can be found in sql database
I hope it was useful
I have a database design and relationships problem and I am concerned with possible circular references.
To give an example, Jack has on his stock Medicines A, B and C. Medicines A and B have an active_ingredient AI1 and medicine C has an active_ingredient AI2.
Jack goes to the doctor, who prescribes him AI1. For the Prescription object, it is indifferent if he takes Medicine A or B.
Here is an example code:
class ActiveIngredient(models.Model):
...
class Medicine(models.Model):
quantity = models.IntegerField()
active_ingredient = models.ForeignKey("ActiveIngredient", on_delete=models.CASCADE)
class Person(models.Model):
...
class PersonStock(models.Model):
customer = models.ForeignKey("Person", on_delete=models.CASCADE)
medicine = models.ForeignKey("Medicine", on_delete=models.CASCADE)
expiration_date = models.DateField()
class Prescription(models.Model):
...
quantity = models.IntegerField()
What is the best solution to model this relationship?
Changing Prescription to this:
class Prescription(models.Model):
...
customer = models.ForeignKey("Person", on_delete=models.CASCADE)
active_ingredient = models.ForeignKey("ActiveIngredient", on_delete=models.CASCADE)
quantity = models.IntegerField()
Seems wrong to me given that there is the PersonStock class already connecting Person and Medicine.
You're right to be concerned about duplicated information; a major concern of database design (specifically database normalization) is avoiding that so as to eliminate the possibility of inconsistent data.
In this case, however, I think it makes more sense to keep prescriptions and their filling separate. These are two separate things, and in the real world it's very possible for mistakes to be made and the wrong medicine to be delivered. While one should endeavor to prevent such mistakes, that's very different from making it impossible to represent a mistake in your data model.
So my recommendation would be to validate the data at the application layer rather than building constraints into the data model itself. Something like:
class ActiveIngredient(models.Model):
...
class Medicine(models.Model):
quantity = models.IntegerField()
active_ingredient = models.ForeignKey("ActiveIngredient", on_delete=models.CASCADE)
class Person(models.Model):
...
class Prescription(models.Model):
...
customer = models.ForeignKey("Person", on_delete=models.CASCADE)
active_ingredient = models.ForeignKey("ActiveIngredient", on_delete=models.CASCADE)
quantity = models.IntegerField()
class PersonStock(models.Model):
prescription = models.ForeignKey("Prescription", on_delete=models.CASCADE)
medicine = models.ForeignKey("Medicine", on_delete=models.CASCADE)
expiration_date = models.DateField()
# Make sure the supplied medicine is correct.
def clean(self):
if self.medicine.active_ingredient != self.prescription.active_ingredient:
raise ValidationError("Wrong medicine!")
Alternatively you could do the check only when a PersonStock is being created.
Such a question, I want to create a price comparison site, there are two ideas how to implement a list of prices from different stores.
First via ForeignKey
class Price(models.Model):
price = models.DecimalField()
shop = models.CharField()
class Product(models.Model):
name = models.CharField(max_length=255)
prices = models.ForeignKey()
JSONfield second method
class Product(models.Model):
name = models.CharField(max_length=255)
data = JSONField()
""" Product.objects.create(name='product', data={'price': 999,
'shop': 'Amazon.com'}
def __str__(self):
return self.name
If anyone has experience, what works faster and more reliable if a large number of goods? Thanks for the early ones.
My Problem:
I have a handful of django models which are setup with various one-to-many relationships. I am trying to retrieve all Books which have a Review (I don't want to retrieve any books whom have no Reviews). Although what I'm trying to do seems relatively straight forward, I'm having real difficulty accomplishing my goal. It seems I may not properly understand how to reach across tables, and any advice anyone could provide in helping me better understand how to get all all Book objects which have a Review stored.
My Models:
class User(models.Model):
"""Creates instances of a `User`."""
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
email = models.CharField(max_length=50)
password = models.CharField(max_length=22)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
objects = UserManager() # Attaches custom `UserManager` methods to our `User.objects` object.
class Author(models.Model):
"""Creates instances of a `Author`."""
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Book(models.Model):
"""Creates instances of a `Book`."""
title = models.CharField(max_length=100)
author = models.ForeignKey(Author, on_delete=models.CASCADE) # ties us into an author for the book. if author deleted, books delete too.
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Review(models.Model):
"""Creates instances of a `Review`."""
description = models.CharField(max_length=500)
user = models.ForeignKey(User, on_delete=models.CASCADE) # ties to user, if user deleted, deletes all user reviews
book = models.ForeignKey(Book, related_name="reviews") # book for review
rating = models.IntegerField() # user rating between 1-5
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
objects = ReviewManager() # Attaches 'ReviewManager' to `Review.objects` methods.
What I've tried:
I've tried giving a related_name="reviews" to my Review.book property, and I've tried accessing reviews via Book.objects.all().reviews_set.all() or similar such queries, using _set.all() and am probably missing something / doing it incorrectly.
Desired Goal:
Retrieve all Book objects, whom have a Review attached to them (not retrieving Book objects whom have no Reviews).
Can anyone help point me in the right direction or tell me what I'm doing wrong? Thank you for your time reading!
Here's my best solution for gathering all books, whom have at least one review. This seems to be accomplishing my needs and answered my original question:
Book.objects.filter(review__gte=1).distinct()
This is saying, from Book model, get any books whom have a review gte (greater than or equal to) 1 -- and make sure they are distinct() ie, no duplicates.
I'm working on a questionnaire model for django that should be maintainable by someone with no programming experience, so I've spent a lot of time crafting my models to compensate for minor details.. Now I want to unlock the potential of SQL database queries to be able to generate statistics about the responses and feedback given.
One of my question types is a 5 star rating, so I would like to be able to gather statistics about the question like:
How many responses for question q were 5 star (, 4star, 3star, etc.)?
What was the average rating response?
Ideally I would like to record these statistic questions in a model, and create a view that shows all the statistics asked and keep the entire thing programmatic.
Should this be a carefully crafted model or set of models like feedback, or is there already some framework or module that handles these situations for me?
My questionnaire/models.py:
class QuestionType(models.Model):
name = models.CharField(max_length=256, blank=True, default="")
class Question(models.Model):
text = models.TextField()
type = models.ForeignKey(QuestionType)
class Response(models.Model):
question = models.ForeignKey(Question)
answer = models.TextField()
class Feedback(models.Model):
user = models.ForeignKey(User)
responses = models.ManyToManyField(Response)
response_time = models.DateTimeField(auto_now_add=True)
This would cover your requirements:
class QuestionType(models.Model):
name = models.CharField(max_length=256, blank=True, default="")
class Question(models.Model):
text = models.TextField()
type = models.ForeignKey(QuestionType)
def how_many_ratings_where_x_stars(self, stars):
return self.rating_set.filter(stars=stars).count()
def average_rating(self, stars):
return self.rating_set.aggregate(models.Avg('stars'))['stars__avg']
class Response(models.Model):
question = models.ForeignKey(Question)
answer = models.TextField()
user = models.ForeignKey(User)
timestamp = models.DateTimeField(auto_now_add=True)
class Rating(models.Model):
question = models.ForeignKey(Question)
stars = models.PositiveIntegerField(min_value=1, max_value=5)
user = models.ForeignKey(User)
timestamp = models.DateTimeField(auto_now_add=True)
class Meta:
unique_together = [('question', 'user')]