Let's say I have an app that's supposed to allow (fashion designers) to post a "Design with Customizations"
The wanted result in the template is like this :
Dress:
Please select material : 1- wool, 2-cotton, 3-cashmere (only one can be selected)
What colours would you like : black $10, blue, red, yellow (multiple selections)
I'd like to allow designers to add options with choices and decide if (customers) can select one choice (radio button group) or multiple choices (checkboxes) with extra charge and decide default ones...
** Models.py **
class Choice(models.Model):
# e.g red
name = models.CharField(max_length=500)
extra_charge = models.DecimalField(default=0, max_digits=10, decimal_places=2)
class Option(models.Model):
# what colours?
name = models.CharField(max_length=500)
choice = models.ForeignKey(Choice)
class Dress(models.Model):
options = models.ManyToManyField(Choice, related_name='Dress')
name = models.CharField(max_length=500)
price = models.DecimalField(max_digits=10, decimal_places=2)
I have been working on Django for a while now but I have no idea how to go about this....
According to my idea, Your Dress Model should not have an option field, also, you should create a foreign key called dress # related to Dress Model in your Option Model.
Each time when you need designers to add an option with choices, just show him the form page created from Option Model, I think this is your solution!
Related
I have the following models:
# Get or create a 'Not selected' category
def get_placeholder_categoy():
category, _ = ListingCategories.objects.get_or_create(category='Not selected')
return category
# Get default's category ID
def get_placeholder_category_id():
return get_placeholder_categoy().id
class ListingCategories(models.Model):
category = models.CharField(max_length=128, unique=True)
def __str__(self):
return f'{self.category}'
class Listing(models.Model):
title = models.CharField(max_length=256)
seller = models.ForeignKey(User, on_delete=models.CASCADE, related_name='listings')
description = models.TextField(max_length=5120, blank=True)
img_url = models.URLField(default='https://media.istockphoto.com/vectors/no-image-available-picture-coming-soon-missing-photo-image-vector-id1379257950?b=1&k=20&m=1379257950&s=170667a&w=0&h=RyBlzT5Jt2U87CNkopCku3Use3c_3bsKS3yj6InGx1I=')
category = models.ForeignKey(ListingCategories, on_delete=models.CASCADE, default=get_placeholder_category_id, related_name='listings')
creation_date = models.DateTimeField()
base_price = models.DecimalField(max_digits=10, decimal_places=2, validators=[
MinValueValidator(0.01),
MaxValueValidator(99999999.99)
])
With these, I have the following form:
class ListingForm(ModelForm):
class Meta:
model = Listing
exclude = ['seller', 'creation_date']
widgets = {
'title': TextInput(attrs=base_html_classes),
'description': Textarea(attrs=base_html_classes),
'img_url': URLInput(attrs=base_html_classes),
'category': Select(attrs=base_html_classes),
'base_price': NumberInput(attrs=base_html_classes)
}
One of the available categories I have is "Not selected", since I want to allow that if at some point a category were to be removed, items can be reassigned to that one, however, when rendering the form, I will do some validation on the view function to prevent it from being submitted if the "not selected" category is sent with the form.
Because of this, I want the HTML form on the template to assign the 'disabled' attribute to the option corresponding to that category, however, I have been searching for a couple of days now without finding anything that I was able to understand to the point where I could try it.
Ideally, another thing I'd like to achieve is to be able to modify the order of the rendered options on the form so that I can move to the top 'not selected' regardless of its primary key within the model.
I am aware I can just create a form instead of a model form, or just modify the template so I manually specify how to render the form itself, but I do feel like there is a simple fix to this either on the model or on the model form that I am just not finding yet.
Thanks in advance!
I would suggest you use (in model definition)
class Listing(models.Model):
..
category = model.ForeignKey(ListingCategories, on_delete=models.SET_NULL, null=True, related_name='listings')
..
and optionally in form definition
class ListingForm(ModelForm):
category = forms.ModelChoiceField(ListingCategories, empty_label='Not Selected')
..
While rendering model form, a required attribute will be automatically added, and in form validating, it is also required. It is only in database validation that the field can be left NULL
I am trying to figure out the best method to add multiple instances of the same field for a Recipe class I have created.
When creating the new Recipe, I need to be able to add multiple instances of Ingredient, Measurement Unit, Unit Value. For example:
ingredient = Lemon
measurement_unit = ml
unit_value = 100
I would then need to add another Ingredient and do the exact same thing. I would then be able to save the Recipe.
What would be the best method to use to achieve this?
UPDATE
Got loads of great suggestions, but perhaps I'm not understanding the context or I'm not explaining things correctly - I am talking specifically about a form repeater - see here: https://themesbrand.com/skote-django/layouts/form-repeater.html?
I want to be able to add another row that would allow me to save multiple instances of ingredients.
The section should look something like this:
Form Repeater
I would create a model for Ingredient and then set a many to many relationship between ingredients and recipes.
Like This:
class Ingredient(models.Model):
name = models.CharField(max_length=150, unique=True)
measurement_unit = models.CharField(max_length=150, unique=True)
unit_value = models.IntegerField()
recipe = models.ManyToManyField(Recipe)
Then from any recipe you could access all the ingredients.
I don't know about the best, but the obvious one is a RecipeIngredient model.
This is a bit more complex than Scrolen's suggestion, but allows multiple recipes to use different amounts of the same ingredient. This becomes useful if there is a fair bit of information you need to attach to an ingredient. Things like supplier, sub-ingredients, allergens, nutritional info, ... you can edit the ingredient, and all the recipes that use it immediately have updated ingredient information.
class Recipe( models.Model):
name = models.CharField( ...)
status = models.CharField( choices = STATUS_CHOICES, ...)
...
class Ingredient( models.Model):
name = models.CharField( unique=True, ...)
...
class RecipeIngredient( models.Model):
recipe = models.ForeignKey( Recipe, models.PROTECT, related_name='ingredients', ...)
ingredient = models.ForeignKey( Ingredient, models.PROTECT, ...)
unit = models.CharField( choices=UNIT_CHOICES, ...)
value = models.FloatField( ...)
usage:
recipe = Recipe( name = 'Lemon Cheesecake', status=Recipe.ON_HOLD )
recipe.save()
# ON_HOLD stops anybody using a recipe only half populated with ingredients
ingredient = Ingredient.objects.get( name='lemon juice')
item = RecipeIngredient(
ingredient=ingredient,
recipe = recipe,
unit='ml',
value=100 )
item.save()
# repeat until all the ingredients are attached to the recipe
# and other stuff such as instructions are also filled in
recipe.status = Recipe.READY
recipe.save()
# now it's ready for somebody to try to cook it!
To get the list:
recipe = Recipe.objects.get( name = 'Lemon Cheesecake')
for item in recipe.ingerdients.all():
item.ingredient.field ... # refers to data in the related Ingredient
item.unit
item.value
I have three models:
Course
Assignment
Term
A course has a ManyToManyField which accesses Django's default User in a field called student, and a ForeignKey with term
An assignment has a ForeignKey with course
Here's the related models:
class Assignment(models.Model):
title = models.CharField(max_length=128, unique=True)
points = models.IntegerField(default=0, blank=True)
description = models.TextField(blank=True)
date_due = models.DateField(blank=True)
time_due = models.TimeField(blank=True)
course = models.ForeignKey(Course)
class Course(models.Model):
subject = models.CharField(max_length=3)
number = models.CharField(max_length=3)
section = models.CharField(max_length=3)
professor = models.ForeignKey("auth.User", limit_choices_to={'groups__name': "Faculty"}, related_name="faculty_profile")
term = models.ForeignKey(Term)
students = models.ManyToManyField("auth.User", limit_choices_to={'groups__name': "Student"}, related_name="student_profile")
When a user logs in to the page, I would like to show them something like this bootstrap collapse card where I can display each term and the corresponding classes with which the student is enrolled.
I am able to access all of the courses in which the student is enrolled, I'm just having difficulty with figuring out the query to select the terms. I've tried using 'select_related' with no luck although I may be using it incorrectly. So far I've got course_list = Course.objects.filter(students = request.user).select_related('term'). Is there a way to acquire all of the terms and their corresponding courses so that I can display them in the way I'd like? If not, should I be modeling my database in a different way?
https://docs.djangoproject.com/en/1.11/ref/models/querysets/#values
You could use values or values_list here to get the fields of the related model Term.
For example expanding on your current request:
To retrieve all the Terms' name and duration for the Courses in your queryset
Course.objects.filter(students = request.user).values('term__name', 'term__duration')
I am not sure what the fields are of your Term model, but you would replace name or duration with whichever you are trying to get at.
I think it helps you
terms = Terms.objects.filter(....) # terms
cources0 = terms[0].course_set.all() # courses for terms[0]
cources0 = terms[0].course_set.filter(students=request.user) # courses for terms[0] for user
It's a little example of my model:
class Food(models.Model):
food = models.CharField(max_length=50)
calories = models.FloatField()
class MenuFood(models.Model):
food = models.ForeignKey('Food')
amount = models.FloatField()
In django admin, when i call template MenuFood i get one ChoiceField with the foods, and TextInput for fill amount, i put extra field in form(TextInput Result).
How can i fill the extra field Result when user select some food or type in TextInput amount or whatever, multiply calories(class Food) * amount(MenuFood)?
Some idea, thanks.
Hay guys, I'm writing a simple app which logs recipes.
I'm working out my models and have stumbled across a problem
My Dish models needs to have many Ingredients. This is no problem because i would do something like this
ingredients = models.ManyToManyfield(Ingredient)
No problems, my dish now can have many ingrendients.
However, the problem is that the ingredient needs to come in different quantities.
I.E 4 eggs, 7 tablespoons sugar
My Ingredient Model is very simple at the moment
class Ingredient(models.Model):
name = models.TextField(blank=False)
slug = models.SlugField(blank=True)
How would i go about work out this problem? What fields would i need to add, would i need to use a 'through' attribute on my ManyToManyfield to solve this problem?
I think you got the right answer with a "through" table ( http://docs.djangoproject.com/en/dev/topics/db/models/#intermediary-manytomany )
Model
class Recipe(models.Model):
name = models.TextField(blank=False)
ingredients = models.ManyToManyField(Ingredient, through='Components')
class Ingredient(models.Model):
name = models.TextField(blank=False)
slug = models.SlugField(blank=True)
class Components(models.Model):
recipe = models.ForeignKey(Recipe)
ingredient = models.ForeignKey(Ingredient)
quantity = models.DecimalField()
You can put unit of quantity (gram, kilo, tablespoon, etc) on Ingredient level, but I think it is better on Ingredients level (for example you can have 1 recipe with 10 Cl of milk but one other with 1L ... So "different" units for a same ingredient.
Data Creation
By Dish you mean Recipe right ? If you have a look to previous link (http://docs.djangoproject.com/en/dev/topics/db/models/#intermediary-manytomany), they give you a good example (based on the beatles).
Basically :
1.Create a Recipe:
cake=Recipe.objects.create(name="Simple Cake")
2.Create several Ingredient (if they doesn't already exist from a previous recipe ;)):
egg = Ingredient.objects.create(name="Egg")
milk = Ingredient.objects.create(name="milk")
3.Create the relationship:
cake_ing1 = Components.objects.create(recipe=cake, ingredient=egg,quantity = 2)
cake_ing2 = Components.objects.create(recipe=cake, ingredient=milk,quantity = 200)
and so on. Plus, I'm now quite sure that unit should go to Components level, with a default unit as "piece" (that would be for yours eggs ...), and would be something like "mL" for milk.
Data Access
In order to get ingredients (Components) of a recipe just do :
cake = Recipe.objects.get(name = "Simple Cake")
components_cake = Components.objects.get(recipe = cake)