Django toggle yes and no - django

I am having difficulty creating a toggle for Django. This Django is a Chores table listed from the description, category, and is_complete. The is_complete is what I am having trouble with. The toggle should be a href that when you click "yes" it will change to "no"
Model.py
class ChoresCategory(models.Model):
category = models.CharField(max_length=128)
def __str__(self):
return self.category
class Chores(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
description = models.CharField(max_length=128)
category = models.ForeignKey(TaskCategory, on_delete=models.CASCADE)
is_completed = models.BooleanField(default=False)
I tried creating a view.py
def toggle(request):

Related

Django - Display child elements based on parent in ModelChoiceField queryset

I have created models that each of them based on own parent. On forms I have used ModelChoiceField. When the user selects the element from Category choice field, on Subcategory field should be displayed only its child elements. And also after selecting the Subcategory, on ProductCategory choice field should be displayed child elements.
it should have been something like this
But I am getting error:
TypeError: Field 'id' expected a number but got <django.forms.models.ModelChoiceField object at 0x7f3d1f9f0ac0>. How can I improve it?
models.py:
class Category(models.Model):
name = models.CharField("Category Name", max_length=100, unique=True)
link = models.CharField("Category Link", max_length=250)
def __str__(self):
return self.name
class Subcategory(models.Model):
parent = models.ForeignKey(Category, on_delete=models.CASCADE, null=True)
name = models.CharField("Sub-category Name", max_length=100, unique=True)
link = models.CharField("Sub-category Link", max_length=250)
def __str__(self):
return self.name
class ProductCategory(models.Model):
parent = models.ForeignKey(Subcategory, on_delete=models.CASCADE, null=True)
name = models.CharField("Product-Category Name", max_length=100, unique=True)
link = models.CharField("Product-Category Link", max_length=250)
def __str__(self):
return self.name
class ProductSubCategory(models.Model):
parent = models.ForeignKey(ProductCategory, on_delete=models.CASCADE, null=True)
name = models.CharField("Product-Sub-Category Name", max_length=100, unique=True)
link = models.CharField("Product-Sub-Category Name", max_length=250)
def __str__(self):
return self.name
forms.py
class CategoryForm(forms.Form):
category = forms.ModelChoiceField(queryset=Category.objects.all())
subcategory = forms.ModelChoiceField(queryset=Subcategory.objects.filter(parent=category))
prodcategory = forms.ModelChoiceField(queryset=ProductCategory.objects.filter(parent=subcategory))
On views.py I am just running external script
def homepage(request):
context = {}
form = CategoryForm()
context['form'] = form
if request.GET:
temp = request.GET['prodcategory']
selected = ProductCategory.objects.get(pk=temp)
scraper = Scraper()
results = scraper.scrape(title=selected, link=selected.link)
data = ProductSubCategory.objects.filter(parent=results)
context['data'] = data
return render(request, 'index.html', context)
There is a well explained article on how to approach chained drop down lists in Django forms :
How to Implement Dependent/Chained Dropdown List with Django
or you could use an external library like django-smart-selects

Filter queryset of django inline formset based on attribute of through model

I have a basic restaurant inventory tracking app that allows the user to create ingredients, menus, and items on the menus. For each item on a given menu, the user can list the required ingredients for that item along with a quantity required per ingredient for that item.
Menu items have a many-to-many relationship with ingredients, and are connected via an "IngredientQuantity" through table.
Here are my models:
class Ingredient(models.Model):
GRAM = 'Grams'
OUNCE = 'Ounces'
PIECE = 'Pieces'
UNIT_CHOICES = [
('Grams', 'Grams'),
('Ounces', 'Ounces'),
('Pieces', 'Pieces')
]
user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
name = models.CharField(max_length=200)
unitType = models.CharField(max_length=200, choices=UNIT_CHOICES, verbose_name='Unit')
unitCost = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='Unit Cost')
inventoryQuantity = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='Quantity')
def __str__(self):
return self.name + ' (' + self.unitType + ')'
def totalCost(self):
result = self.inventoryQuantity * self.unitCost
return "{:.0f}".format(result)
class Menu(models.Model):
user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
name = models.CharField(max_length=200)
timeCreated = models.DateTimeField(auto_now_add=True)
timeUpdated = models.DateTimeField(auto_now=True)
def __str__(self):
return str(self.name)
class MenuItem(models.Model):
user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
name = models.CharField(max_length=200)
price = models.DecimalField(max_digits=10, decimal_places=2)
ingredients = models.ManyToManyField(Ingredient, through='IngredientQuantity')
menu = models.ForeignKey(Menu, on_delete=models.CASCADE, null=True)
def __str__(self):
return self.name
def itemCost(self):
relevantIngredients = IngredientQuantity.objects.filter(menuItem=self)
cost = 0
for ingredient in relevantIngredients:
cost += (ingredient.ingredient.unitCost * ingredient.ingredientQuantity)
return cost
class IngredientQuantity(models.Model):
user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
ingredient = models.ForeignKey(Ingredient, on_delete=models.CASCADE)
menuItem = models.ForeignKey(MenuItem, on_delete=models.CASCADE)
ingredientQuantity = models.IntegerField(default=0)
def __str__(self):
return str(self.ingredient)
This is a multi-user app, so when a user creates a new item on a menu and adds ingredients to it, they should only have the option of choosing ingredients they have created, not those of other users. Here is my attempt to do that in my views:
def ItemUpdate(request, pk):
item = MenuItem.objects.get(id=pk)
user = request.user
IngredientQuantityFormset = inlineformset_factory(
MenuItem, IngredientQuantity, fields=('ingredient', 'ingredientQuantity'), can_delete=True, extra=0
)
form = ItemCreateForm(instance=item)
formset = IngredientQuantityFormset(instance=item, queryset=IngredientQuantity.objects.filter(ingredient__user=user))
if request.method == 'POST':
form = ItemCreateForm(request.POST, instance=item)
formset = IngredientQuantityFormset(request.POST, instance=item, queryset=IngredientQuantity.objects.filter(ingredient__user=user))
# rest of view...
I've searched everywhere for how to implement the queryset parameter properly, but I cannot get it to work. When creating an item on a menu, the user still has the ability to choose from every ingredient in the database (including the ones created by other users). I would like the user to only be able to choose from the ingredients they themselves created.
Does anyone know how to do this properly? Thank you!
I received some guidance on Django forums and arrived at a solution which is documented below:
https://forum.djangoproject.com/t/filter-dropdown-options-in-django-inline-formset-based-on-attribute-of-through-model/13374/3

Add a "+" button that opens a popup inside my django model form

I want to add a "+" button that opens a popup inside my django model form.. Any idea about that?
My code in models.py
class library(models.Model):
book_name = models.CharField(max_length=50, null=True, blank=True)
author = models.ForeignKey(User, on_delete=models.CASCADE, limit_choices_to={'is_superuser': True}, null=True,
blank=True)
description = models.TextField(null=True, blank=True)
duration = models.DurationField(null=True, blank=True)
date = models.DateField()
book_image = models.ImageField(upload_to='lib/book_img', null=True, blank=True)
parallel to author field i want to add a "+" button(To add new author) that opens a popup modal form.
my forms.py is
class library_details(forms.ModelForm):
class Meta:
model = library
fields = "__all__"
You could use bootstrap modal.
https://getbootstrap.com/docs/4.0/components/modal/
You'd just have to add a form field that is blank but set the attributes that are necessary to open the modal.
Something like the below
NOTE: I have not tested this.
class library_details(forms.ModelForm):
checkbox = forms.CheckboxInput()
class Meta:
model = library
fields = "__all__"
def __init__(self, *args, **kwargs):
super(library_details, self).__init__(*args, **kwargs)
self.fields['checkbox'].widget.attrs['data-toggle'] = "modal"
self.fields['checkbox'].widget.attrs['data-target'] = "#exampleModal"

How to add Category while adding product in Django form? Just like the Django admin form

So I am trying to build an inventory system.
I have 2 models, Categories and Product connected through the ManyToMany field.
I want to add a category while I am adding the product just like it happens in the Django admin form.
How can I do that?
My model.py File
class Categories(models.Model):
name = models.CharField(max_length=30)
organisation = models.ForeignKey(UserProfile, on_delete=models.CASCADE)
def __str__(self):
return f"{self.name}"
class Product(models.Model):
category = models.ManyToManyField(Categories)
brand = models.CharField(max_length=20)
model = models.CharField(max_length=20)
hac = models.CharField(max_length=20, null=True, blank=True)
rate = models.DecimalField(max_digits=6, decimal_places=2)
stock = models.IntegerField(default=0)
# organisation = models.ForeignKey(UserProfile, on_delete=models.CASCADE)
date_added = models.DateTimeField(auto_now_add=True)
date_updated = models.DateTimeField(auto_now=True)
def __str__(self):
return f"{self.brand} {self.model} "
My form.py file
class ProductModelForm(forms.ModelForm):
class Meta:
model = Product
fields = '__all__'
**My code output **
See the below screenshots to understand what I want to do. I basically want that plus button option to add a category from the product form itself.
You should show snippets of codes that we need to provide an answer.

How to show specific subcategory for a selected category in django

Recently I'm working on a blog. where a post has category and subcategory.
This is my models.py
from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone
from ckeditor_uploader.fields import RichTextUploadingField
class Category(models.Model):
title = models.CharField(max_length=50, unique=True)
def __str__(self):
return f"{self.title}"
class SubCategory(models.Model):
category = models.ForeignKey(Category, on_delete=models.CASCADE)
title = models.CharField(max_length=50, unique=True)
def __str__(self):
return f"{self.title}"
class Author(models.Model):
name = models.CharField(max_length=100)
email = models.EmailField(max_length=100)
phone_no = models.CharField(max_length=14)
details = models.TextField(null=True,blank=True)
def __str__(self):
return f"{self.name}"
class Post(models.Model):
author = models.ForeignKey(Author, default=1,blank=True,
null=True, on_delete=models.SET_DEFAULT)
category = models.ForeignKey(Category,on_delete=models.CASCADE,
null=True)
sub_category = models.ForeignKey(SubCategory,
on_delete=models.CASCADE, null=True, blank=True)
title = models.CharField(max_length=250)
featured_image = models.ImageField(
upload_to="post_featured_image",null=False )
content = RichTextUploadingField()
podcast = models.FileField(upload_to="post_podcast",
blank=True,null=True)
uploaded_on = models.DateTimeField(default=timezone.now)
viewed = models.IntegerField(default=0,editable=False)
def __str__(self):
return f"{self.title}"
Now I can choose category and subcategory for a post from Django admin panel. But the problem is I can choose one category and any subcategory even the subcategory is not the child of the selected category. So a post has a category and a subcategory. But the subcategory's parent category is not same as post's category. So I want that I can only choose those subcategories which is the child of selected categories that I choose for the post. Like next field has to be dependent on the previous field. How to do that?
sorry for my bad English. Thank you.