Fill form fields dynamically in django - python

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.

Related

How to query a model made up of multiple Foreign Keys

I'm doing the CS50 Web programming course, learning to use Django. The learning exercise basically has you recreating this pizza restaurant menu with django.
I've created some models for the data, and now I'm trying to use Django templating to create a menu page for the pizzas.
Here are my models:
from django.db import models
class intToppings(models.Model):
name = models.CharField(max_length=16)
intToppings = models.IntegerField() # 0 Cheese, 1/2/3, 5 Special
def __str__(self):
return f"{self.name}"
class Size(models.Model):
size = models.CharField(max_length=16)
def __str__(self):
return f"{self.size}"
class PizzaBase(models.Model):
base = models.CharField(max_length=16)
def __str__(self):
return f"{self.base}"
class Toppings(models.Model):
topping = models.CharField(max_length=32)
def __str__(self):
return f"{self.topping}"
class Pizza(models.Model):
size = models.ForeignKey(Size, on_delete=models.CASCADE) # CASCADE will delete all Regular Pizzas if their size is deleted (as opposed to .SET_NULL)
base = models.ForeignKey(PizzaBase, on_delete=models.CASCADE)
intToppings = models.ForeignKey(intToppings, on_delete=models.CASCADE)
price = models.IntegerField() # price in cents
def __str__(self):
return f"{self.size} {self.base} {self.intToppings} Pizza"
There's an entry "small" and "large" in the Size db, and for intToppings there is one entry with name "cheese" and an int of 0, another for "1 topping" with an int of 1, etc.
And for the Pizza model, I made an entry for every combo on the menu, ie:
<QuerySet [<Pizza: small Regular Cheese Pizza>, <Pizza: small Regular 1 Topping Pizza>, <Pizza: small Regular 2 Toppings Pizza>, ...
... <Pizza: large Sicilian 2 Toppings Pizza>, <Pizza: large Sicilian 3 Toppings Pizza>, <Pizza: large Sicilian Special Pizza>]>
On my views.py, I can't really pass that whole data set to the django template because it's not sensible/possible to loop through it to create an html table. (my html table is identical to the one on their website, one table for regular pizza, one for sicilian.)
I'm trying to solve this issue by first constructing a list/array or dict object that will pass data to the django template in a structure that is easy to loop through. And to do this I want to query the Pizza model.
Essentially, all I'm looking to do is (pseudo code: SELECT Pizza WHERE size="small" base="Regular", intToppings=0 and get the price for that pizza.
I don't seem to be able to query the foreign keys though;
Pizza.objects.all().filter(price=1220)
works but isn't what I need. What I need is;
p = Pizza.objects.all().filter(base="Regular", size="small", intToppings=0)
print(p.price)
which doesn't work.
Have you tried to use the field names of the related models? Like this:
p = Pizza.objects.filter(
base__base="Regular",
size__size="small",
intToppings__intToppings=0)
print(p)
Like the docs say,
you first access the related model (say base) and then you access the field of that related model (__base) and compare that to the string you want, resulting in base__base='something'.
Maybe you even could rename the field PizzaBase.base to PizzaBase.name to make it less confusing.
Try this:
p = Pizza.objects.filter(
base__base = "Regular",
size__size = "small",
intToppings_id = 0,
)
Note that I changed intToppings to intToppings_id. If you need to filter by a foreign key, you can pass in the intToppings object, or you can add _id to the end of the column name and simply insert the pk value.

How to add multiple foreign key in Django

I am beginner in Django.
I am having two models
class Employee(models.Model):
full_name = models.CharField(max_length=120,default=None)
designation = models.CharField(max_length=80,default=None)
class Leave(models.Model):
employee = models.ForeignKey(Employee, related_name='employee')
number_of_days = models.IntegerField(default=0)
Now I have inline Leave Model with Employee in admin.py
so that I can add as many leaves I want in employees
But when I retrieve this model in views new Leaves are created, all I want is one employee should show total = number of days, but it creates new leaves, not able to build any logic here I am stuck, please ask if u don't understand what I am asking.
Not exactly sure what you are asking, but my guess is you want to display the total number of absent days of an employee in the admin. You can use aggregation and Sum in particular and a custom method on your model:
# models
from django.db.models import Sum
class Employee(models.Model):
def absent_days(self):
return self.leaves.aggregate(s=Sum('number_of_days'))['s'] or 0
absent_days.short_description = 'Absent days' # used as column header/field label
class Leave(models.Model):
# note the changed related name!
employee = models.ForeignKey(Employee, related_name='leaves')
# admin
class EmployeeAdmin(admin.ModelAdmin):
readonly_fields = [..., 'absent_days', ...]
fields = [..., 'absent_days', ...]
list_display = [..., 'absent_days', ...]

Display editable decimal field with trailing currency symbol in admin interface (Django)

I have a simple model:
class Product(models.Model):
...
price = models.DecimalField(max_digits=4, decimal_places=2)
...
def price_currency(self):
return '%.2f €' % self.price
And admin model:
class ProductAdmin(admin.ModelAdmin):
list_display = ['price_currency']
Achieves this list overview of products (only price column screenshot):
The problem is that this field is not editable (in list view). Is there a way to make it editable and display the trailing currency symbol at the end?
I can just call list_display = ['price'] and list_editable = ['price'], the problem is that then it does not show the euro sign at the end, ie:
My ideal end goal would be:

allow users to design forms with choices

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!

Filtering by foreign key in dropdown

I'm using django-filters.
My Car model has a Manufacturer foreign key . What I want to do is Filter the Cars by a dropdown that is populated with all Manufacturers in the database.
class Car(models.Model):
slug = models.SlugField(unique=True)
name = models.CharField(max_length=256)
cost = models.DecimalField(max_digits=10,decimal_places=5)
manufacturer = models.ForeignKey(Manufacturer)
My filter currently is a blank text field, you can enter a manufacturer name and then submit to filter this way. The Dropdown would be much more suitable, but I haven't been able to find a way to do this. Here is the filter model as it is now:
class CarFilter(django_filters.FilterSet):
manufacturer = django_filters.CharFilter(name="manufacturer__name")
class Meta:
model = Car
fields = ['name', 'manufacturer']
Just don't define the manufacturer filter field at all and django-filter will use the default filter for this field (which is a drop down). So something like this should be working:
class CarFilter(django_filters.FilterSet):
class Meta:
model = Car
fields = ['name', 'manufacturer']

Categories