Hi I'm new to programming and I am building a recipe website to learn, what I am struggling with though is how to handle recipe ingredients? I would like to do the following:
Have global recipe ingredients i.e. common ingredients, chicken, beef etc.
Allow users to create their own ingredients (for that user only) i.e. big tomato
Attach ingredients to a recipe regardless of if they are global or user created
Allow users to add ingredients to their pantry and how much of the ingredient they have in stock
What I think the models would like is below, but I'm not sure if this is correct or the best method, any advice appreciated.
recipe/models.py
User = settings.AUTH_USER_MODEL
class Recipe(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
recipeName = models.CharField(max_length=220) # grilled chicken pasta
userRecipeIngredients = models.ManyToManyField(UserCreatedIngredient, blank=True, Null=True, through='IngredientToRecipe')
globalRecipeIngredients = models.ManyToManyField(GlobalIngredient, blank=True, Null=True, through='IngredientToRecipe')
class UserCreatedIngredient(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
name = models.CharField(max_length=220) # grilled chicken
class GlobalIngredient(models.Model):
name = models.CharField(max_length=220) # chicken
class IngredientToRecipe(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
userIngredient = models.ForeignKey(UserCreatedIngredient, on_delete=models.SET_NULL)
globalIngredient = models.ForeignKey(GlobalIngredient, on_delete=models.SET_NULL)
quantity = models.CharField(max_length=50, blank=True, null=True) # 400
unit = models.CharField(max_length=50, blank=True, null=True) # pounds, lbs, oz ,grams, etc
instructions = models.TextField(blank=True, null=True) # chopped, diced etc.
pantry/models.py:
from recipes.models import IngredientToRecipe
User = settings.AUTH_USER_MODEL
class pantryIngredients(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
ingredients = models.ForeignKey(IngredientToRecipe, on_delete=models.SET_NULL)
inStock = = models.IntegerField(default=0, blank=False) # user can increment i.e. two chicken in stock
One way to address the first three requirements in your question would be to build inheritance into your models.
class Recipe(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
recipeName = models.CharField(max_length=220) # grilled chicken pasta
ingredients = models.ManyToManyField(Ingredient, blank=True, Null=True, through='IngredientToRecipe')
class Ingredient(models.Model):
name = models.CharField(max_length=220)
class GlobalIngredient(Ingredient):
pass
class UserCreatedIngredient(Ingredient):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
class IngredientToRecipe(models.Model):
ingredient = models.ForeignKey(Ingredient, on_delete=models.SET_NULL)
quantity = models.CharField(max_length=50, blank=True, null=True) # 400
unit = models.CharField(max_length=50, blank=True, null=True) # pounds, lbs, oz ,grams, etc
instructions = models.TextField(blank=True, null=True) # chopped, diced etc.
By allowing this inheritance to take place you can improve data redundancy.
Related
class City(models.Model):
name = models.CharField(max_length=200, null=True, blank=False)
class District(models.Model):
city = models.ForeignKey(City, on_delete=models.SET_NULL, null=True)
name = models.CharField(max_length=200, null=True, blank=False)
class ShippingAddress(models.Model):
city = models.ForeignKey(City, on_delete=models.CASCADE, null=False)
district = models.ForeignKey(District, on_delete=models.CASCADE, null=False)
I would like to filter the admin panel by city (selected city). in order to filter too much similar districts names.
If someone has another way to do it no problem, that was a junior try, waiting for your advice.
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)
I'm learning Django and I'm trying to make a sort of wiki type app. In this wiki there are different type of models: Characters, Items, Spells and Adventures. Each model has some fields that are the same (like name, author, date_created, etc.) and some that are unique to the model, like duration for adventures, alignment for characters, etc. The problem that I have is that if they are different models then every time I want to make something that is common to all of the models (like being able to like, favorite, create, edit, etc.) then I have to code for each model individually. Is there a way of creating a sort of Content model that contains every character, item, spell and adventure so that every time I want to make a form or a function I just make a Content form or Content function?
Here's some of the code, some parts are in spanish but I translated the important parts:
class Character(models.Model):
ALIGNMENT= (
('Legal Bueno', 'Legal Bueno'),
('Legal Neutral', 'Legal Neutral'),
('Legal Malvado', 'Legal Malvado'),
('Neutral Bueno', 'Neutral Bueno'),
('Neutral', 'Neutral'),
('Neutral Malvado', 'Neutral Malvado'),
('Caótico Bueno', 'Caótico Bueno'),
('Caótico Neutral', 'Caótico Neutral'),
('Caótico Malvado', 'Caótico Malvado')
)
name = models.CharField(max_length=50)
author = models.ForeignKey(Usuario, null=True, on_delete=models.CASCADE, editable=False, related_name='personajes')
alignment = models.CharField(max_length=50, choices=ALIGNMENT)
description= models.CharField(max_length=200, null=True)
likes = models.ManyToManyField(Usuario, blank=True, related_name='personaje_likes')
favorites = models.ManyToManyField(Usuario, blank=True, related_name='personaje_favoritos')
class Item(models.Model):
name = models.CharField(max_length=50)
author = models.ForeignKey(Usuario, null=True, on_delete=models.CASCADE, editable=False, related_name='items')
description= models.CharField(max_length=200, null=True)
likes = models.ManyToManyField(Usuario, blank=True, related_name='item_likes')
favorites = models.ManyToManyField(Usuario, blank=True, related_name='item_favoritos')
class Spell(models.Model):
name = models.CharField(max_length=50)
author = models.ForeignKey(Usuario, null=True, on_delete=models.CASCADE, editable=False, related_name='hechizos')
description= models.CharField(max_length=200, null=True)
likes = models.ManyToManyField(Usuario, blank=True, related_name='hechizo_likes')
favorites = models.ManyToManyField(Usuario, blank=True, related_name='hechizo_favoritos')
class Adventure(models.Model):
DURATION = (
('Corta', 'Corta'),
('Mediana', 'Mediana'),
('Larga', 'Larga')
)
name = models.CharField(max_length=50)
author = models.ForeignKey(Usuario, null=True, on_delete=models.CASCADE, editable=False, related_name='aventuras')
duration = models.CharField(max_length=50, choices=DURATION)
description = models.CharField(max_length=200)
likes = models.ManyToManyField(Usuario, blank=True, related_name='aventura_likes')
favorites = models.ManyToManyField(Usuario, blank=True, related_name='aventura_favoritos')
I think you can create a base model and then use a OneToOneField to this model in your other models.
class BaseContent(models.Model):
name = models.CharField(max_length=500)
author= models.CharField(max_length=500)
(...)
class Characters(models.Model):
base_content = models.OneToOneField(BaseContent, on_delete=models.CASCADE)
(...)
Current Database Schema -
I have these 3 tables, Curriculum, Assignment, and Student. Every Student is assigned a Curriculum through a ForeginKey relationship between Student and Curriculum. Every
Assignment possesses the same relation with the Curriculum using a ForeginKey.
Problem Statement -
There are around 100 Assignments for each Curriculum, the problem is, some students need to be exempt from some assignments, so I want a way that I can exempt a Student from Assignments 1, 2, and 3 but have the rest of the students do the assignment 1, 2 and 3.
My solution that failed -
What I tried was, creating a ManyToManyField in Student table in relation to Assignment table. However, having to add hundreds of assignments manually would be ridiculously time-consuming for each student.
class Curriculum(models.Model):
name = models.CharField(max_length=50, null=False)
subject = models.CharField(max_length=30, choices=SUBJECT)
grade_level = models.CharField(max_length=20, choices=CURRICULUMGRADE, null=False)
tracking = models.CharField(max_length=20, choices=TRACKING, null=False)
required = models.CharField(max_length=20, null=True)
recorded_from = models.CharField(max_length=20, choices=RECORDED, null=False)
semesterend = models.CharField(max_length=50, null=True)
username = models.CharField(max_length=50, null=True)
password = models.CharField(max_length=50, null=True)
loginurl = models.CharField(max_length=100, null=True)
weight = models.IntegerField(null=True)
level = models.CharField(max_length=20, choices=LEVEL, null=False)
class Student(models.Model):
epicenter_id = models.CharField(
null=False, blank=False, unique=True, max_length=10
)
last_name = models.CharField(null=False, max_length=50)
first_name = models.CharField(null=False, max_length=50)
email = models.EmailField(null=False, max_length=120)
phone_number = models.CharField(null=False, max_length=50)
additional_email = models.EmailField(max_length=120, null=True)
additional_phone_number = models.CharField(max_length=20, null=True)
grade = models.CharField(max_length=20, choices=GRADELEVEL, null=False)
curriculum = models.ForeginKey('curriculum', null=True, blank=True, on_delete=models.SET_NULL)
class Assignment(models.Model):
standard = models.ManyToManyField(
Standard)
curriculum = models.ForeignKey(
Curriculum, on_delete=models.CASCADE, related_name="curriculum_assignment"
)
name = models.CharField(max_length=500, null=False)
description = models.CharField(max_length=500, null=False)
status = models.CharField(max_length=30, choices=STATUS, null=False)
type_of = models.CharField(max_length=30, choices=TYPE, null=False)
Alright, so the best solution I could think of was creating another table to store all the exempted assignments, called ExemptAssignements.
models.py
class ExemptAssignments(models.Model):
student = models.ForeginKey('student', null=True, blank=True, on_delete=models.SET_NULL)
assignments = models.ManyToMany('assignment', null=True, blank=True)
Now anytime I want to exempt the students from any Assignments, I can manually select them through the admin panel, as well the Student who's being exempted.
Now to get a list of all the assignments excluding the ones I have exempted I can simply use.
student = Student.objects.first()
Assignment.objects.filter(curriculum=student.curriculum).exclude(id__in=[x.id for x i in ExemptAssignment.objects.filter(student=student).assignment.all()]
And the above query will only show the Assignments which haven't been exempted.
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.