Getting the entries of a ManyToManyField - python

I'm working with a ManyToManyField and using a ModelMultipleChoice on form, I want to get the entries, but all I get is appname.Extra.none
models.py
class Extra(models.Model):
extra_n = models.CharField(max_length=200)
extra_price = models.IntegerField(default=0)
def __str__(self):
return self.extra_n
class Meal(models.Model):
restaurant = models.ForeignKey(Restaurant, on_delete=models.PROTECT)
category = models.ForeignKey(MealCategory, on_delete=models.PROTECT)
name = models.CharField(max_length=500)
short_description = models.CharField(max_length=500)
image = models.ImageField(upload_to='meal_images/', blank=False)
price = models.IntegerField(default=0)
extras = models.ManyToManyField(Extra, related_name='extras')
def __str__(self):
return self.name
forms.py
class MealForm(forms.ModelForm):
extras = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple(), queryset=Meal.extras)
class Meta:
model = Meal
exclude = ("restaurant",)
views.py
def restaurant_meal(request):
meals = Meal.objects.filter(restaurant = request.user.restaurant).order_by("-id")
return render(request, 'restaurant/meal.html', {"meals": meals})
The output desired is getting the extras added displayed on restaurant_meal view.

you can try change
meals = Meal.objects.filter(restaurant = request.user.restaurant).order_by("-id")
to
meals = Meal.objects.filter(restaurant = request.user.restaurant).prefetch_related('extras').order_by("-id")
and try again.
Doc of this in prefetch_related

Related

drf viewset : multiple choices

I tried to make method(location_item) that shows item by region.
And I want to implement the 'gu, dong' field(in location model) with multiple choices.
so, wrote this method code. but filtering doesn't work..
This shows all item objects, not just the objects I want.
TypeError: Field 'id' expected a number but got <Item: 애니원모어 원피스입니다!>.
[13/Aug/2022 15:01:07] "GET /item_post/location/location_item/ HTTP/1.1" 500 152955
I don't know what sholud i do.
please help me...
models.py
class Item(models.Model):
user_id = models.ForeignKey(User, related_name='item_sets', on_delete=models.CASCADE)
category_id = models.ForeignKey(Category, related_name='item_sets', on_delete=models.DO_NOTHING)
description = models.TextField()
feature = models.TextField()
product_defect = models.TextField()
size = models.CharField(max_length=6)
wear_count = models.IntegerField()
price = models.IntegerField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.description
class Location(models.Model):
city = models.CharField(max_length=10)
gu = models.CharField(max_length=10)
dong = models.CharField(max_length=10)
def __str__(self):
return self.city+" "+self.gu+" "+self.dong
class LocationSet(models.Model):
item_id = models.ForeignKey(Item, on_delete=models.CASCADE, related_name='location_sets')
location_id = models.ForeignKey(Location, on_delete=models.CASCADE, related_name='location_sets')
serializers.py
class ItemSerializer(serializers.ModelSerializer):
photos = PhotoSerializer(source='photo_sets', many=True, read_only=True)
style_photos = StylePhotoSerializer(source='style_photo_sets', many=True, read_only=True)
class Meta:
model = Item
fields = '__all__'
class LocationSerializer(serializers.ModelSerializer):
class Meta:
model = Location
fields = '__all__'
class LocationSetSerializer(serializers.ModelSerializer):
class Meta:
model = LocationSet
fields = '__all__'
views.py
class ItemViewSet(ModelViewSet):
queryset = Item.objects.all()
serializer_class = ItemSerializer
filter_backends = [SearchFilter, OrderingFilter]
search_fields = ['description'] # ?search=
ordering_fields = ['-created_at'] # ?ordering=
ordering = ['-created_at']
# here
#action(detail=False, methods=['GET'])
def location_item(self, request):
locations = Location.objects.all()
city = request.GET.get('city', None)
gu = request.GET.getlist('gu', None) # multiple choices
dong = request.GET.getlist('dong', None) # multiple choices
print(city, " ", gu, " ", dong) # > None [] [] (upper codes not work..)
if city:
locations = locations.filter(city=city)
if gu:
locations = locations.filter(gu__in=gu).distinct()
if dong:
locations = locations.filter(dong__in=dong).distinct()
location_ids = []
for i in locations:
location_ids.append(i.id)
locationsets = LocationSet.objects.filter(location_id__in=location_ids)
item_ids = []
for i in locationsets:
item_ids.append(i.item_id)
serializer = self.get_serializer(item_ids, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
To create method that shows items by region.
what sholud i do?
I think the last lines of code are wrong.
...
#action(detail=False, methods=['GET'])
def location_item(self, request):
...
# here I changed the last four lines
item_ids = [x.item_id for x in locationsets]
serializer = self.get_serializer(item_id__id__in = item_ids, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)

Not able to Update CRUD data with foreign keys despite putting correct namings

I am doing CRUD data which has foreign keys and serializers(since I am told to use serializers instead of Forms),even though I have put the correct model and it's names in the product_edit page, the data is showing blank instead of thier saved data ,the wrong sub_category name is coming,this is how the edit page currently looks
serializer:
class CategoriesSerializer(serializers.ModelSerializer):
class Meta:
model = Categories
fields = "__all__"
extra_kwargs = {'category_name': {'required': False}}
class ColorsSerializer(serializers.ModelSerializer):
class Meta:
model = Colors
fields = "__all__"
class POLLSerializer(serializers.ModelSerializer):
# categories = serializers.StringRelatedField(many=False)
# sub_categories = serializers.StringRelatedField(many=False)
# color = serializers.StringRelatedField(many=False)
# size = serializers.StringRelatedField(many=False)
class Meta:
model = Products
fields = "__all__"
class SizeSerializer(serializers.ModelSerializer):
class Meta:
model = Size
fields = "__all__"
class SUBCategoriesSerializer(serializers.ModelSerializer):
class Meta:
model = SUBCategories
fields = "__all__"
below are the models of my CRUD
class Products(models.Model):
categories = models.ForeignKey(Categories,on_delete=models.CASCADE)
sub_categories = models.ForeignKey(SUBCategories,on_delete=models.CASCADE)
color = models.ForeignKey(Colors,on_delete=models.CASCADE)
size = models.ForeignKey(Size,on_delete=models.CASCADE)
# image = models.ImageField(upload_to = 'media/',width_field=None,height_field=None,null=True)
title = models.CharField(max_length=50)
price = models.CharField(max_length=10)
sku_number = models.CharField(max_length=10)
product_details = models.CharField(max_length=300)
quantity = models.IntegerField(default=0)
isactive = models.BooleanField(default=True)
class Categories(models.Model):
#made changes to category_name for null and blank
category_name = models.CharField(max_length=20)
category_description = models.CharField(max_length=20)
isactive = models.BooleanField(default=True)
def __str__(self):
return self.category_name
class Colors(models.Model):
color_name = models.CharField(max_length=10)
color_description = models.CharField(max_length=10)
isactive = models.BooleanField(default=True)
def __str__(self):
return self.color_name
class Size(models.Model):
size_name = models.CharField(max_length=10)
size_description = models.CharField(max_length=20)
isactive = models.BooleanField(default=True)
def __str__(self):
return self.size_name
class SUBCategories(models.Model):
category_name = models.ForeignKey(Categories, on_delete=models.CASCADE)
sub_categories_name = models.CharField(max_length=20)
sub_categories_description = models.CharField(max_length=20)
isactive = models.BooleanField(default=True)
def __str__(self):
return self.sub_categories_name
update function
def update(request,id):
if request.method == 'GET':
print('GET',id)
edit_products = SUBCategories.objects.filter(id=id).first()
s= SUBCategoriesSerializer(edit_products)
category_dict = Categories.objects.filter(isactive=True)
category = CategoriesSerializer(category_dict, many=True)
sub_category_dict = SUBCategories.objects.filter(isactive=True)
sub_category = SUBCategoriesSerializer(sub_category_dict,many=True)
color_dict = Colors.objects.filter(isactive=True)
color = ColorsSerializer(color_dict,many=True)
size_dict = Size.objects.filter(isactive=True)
size = SizeSerializer(size_dict,many=True)
hm = {"context": category.data,"sub_context":sub_category.data,"color_context":color.data,"size_context":size.data,"SUBCategories":s.data}
return render(request,'polls/product_edit.html',hm)
else:
print('POST',id)
editproducts = {}
d = Products.objects.filter(id=id).first()
if d:
editproducts['categories']=request.POST.get('categories')
editproducts['sub_categories']=request.POST.get('sub_categories')
editproducts['color']=request.POST.get('color')
editproducts['size']=request.POST.get('size')
editproducts['title']=request.POST.get('title')
editproducts['price']=request.POST.get('price')
editproducts['sku_number']=request.POST.get('sku_number')
editproducts['product_details']=request.POST.get('product_details')
# print(editsubcategories)
form = SUBCategoriesSerializer(d,data= editproducts)
if form.is_valid():
form.save()
print("form data",form.data)
print('form error',form.errors)
messages.success(request,'Record Updated Successfully...!:)')
return redirect('polls:show')
else:
print(form.errors)
return redirect("polls:show")
where am I going wrong in the code?
you must create product serializer like below
class ProductSerial(ModelSerializer):
class Meta:
model = Products
fields = '__all__'
and pass editproducts to this serializer
and also you have to be careful that pass id's of
categories
sub_categories
color
size
into request.POST data

How can I implement the same widget that Django uses to ManyToMany fields in the admin page?

My models:
class Ingredient(models.Model):
BASE_UNIT_CHOICES = [("g", "Grams"), ("ml", "Mililiters")]
CURRENCY_CHOICES = [("USD", "US Dollars"), ("EUR", "Euro")]
ingredient_id = models.AutoField(primary_key=True)
name = models.CharField(max_length=200)
base_unit = models.CharField(max_length=2, choices=BASE_UNIT_CHOICES)
cost_per_base_unit = models.FloatField()
currency = models.CharField(
max_length=3, choices=CURRENCY_CHOICES, default="EUR")
def __str__(self):
return self.name
class RecipeIngredient(models.Model):
quantity = models.FloatField()
ingredient_id = models.ForeignKey(Ingredient, on_delete=models.CASCADE)
def __str__(self):
return f"{self.quantity} / {self.ingredient_id}"
class Recipe(models.Model):
recipe_id = models.AutoField(primary_key=True)
name = models.CharField(max_length=200)
ingredients = models.ManyToManyField(RecipeIngredient)
date_created = models.DateTimeField('Date Created')
def __str__(self):
return f"{self.name}, {self.ingredients}"
When I use the admin page, it has this + button that allows me to create new ingredient/quantity combinations
like this
But when I try to use it from a form in my code it looks like
this
Here is my form code:
class AddRecipeForm(forms.ModelForm):
class Meta:
model = Recipe
fields = ['name', 'ingredients', 'date_created']
You should write the 'widgets' for each field in you Form that need configuration.
Check the documentation 'Widgets in forms', or even, you can define your own Widgets.

Error 'Product' object has no attribute '_combinator_query'

I am creating an e-commerce website in django where the homepage can be changed dynamically by changing the instances of FeaturedProduct objects. These objects have two ForeignKeys. First is to the Product class and the other is to FeaturedCategory class(this is for the type of deal, eg: daily deals, new arrivals, etc). So, I'm trying to get the Product instances in a queryset instead of the FeaturedProduct queryset. When I union two querysets, I get an error that 'Product' object has no attribute '_combinator_query'. The codes have been shown below.
My models.py
class Product(models.Model):
product_id = models.AutoField
product_name = models.CharField(max_length=50, unique=True)
category = models.ForeignKey(Category, on_delete=models.SET_DEFAULT, default='1')
sub_category = models.ForeignKey(SubCategory, on_delete=models.SET_DEFAULT, default='2')
price = models.IntegerField(default=0)
stock = models.IntegerField(default=0)
desc = models.TextField()
pub_date = models.DateField()
avg_rating = models.IntegerField(default=0)
avg_rating_float = models.FloatField(default=0.0)
number_of_ratings = models.IntegerField(default=0)
image1 = models.ImageField(upload_to="images", default="")
image2 = models.ImageField(upload_to="images", default="")
image3 = models.ImageField(upload_to="images", default="")
slug = models.SlugField(blank=True, help_text=('Leave this parameter empty, it will get generated automatically.'))
def save(self, *args, **kwargs):
self.slug = slugify(self.product_name)
super(Product, self).save(*args, **kwargs)
def __str__(self):
return self.product_name
class FeaturedCategory(models.Model):
category = models.CharField(max_length=100)
def __str__(self):
return self.category
class Meta:
verbose_name_plural = "Featured Categories"
class FeaturedProduct(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE)
featured_category = models.ForeignKey(FeaturedCategory, on_delete=models.CASCADE)
def __str__(self):
return self.product.product_name
My views.py
def index(request):
prod = Product.objects.none()
feat = FeaturedProduct.objects.all()
for pro in feat:
ob = Product.objects.get(product_name=pro.product)
print(ob.product_name)
print(ob.category)
print(ob.sub_category)
print(ob.price)
prod.union(ob) # Error found here
# Working part
products = Product.objects.all()
context = {'products': products}
return render(request, 'index.html', context)
The last three lines are working fine, but not the other part of the index function.
Please help. Thank You.

AttributeError; Dynamic url for list of charts by category issue (queryset filter)

Django 'CategorisedListView' object has no attribute 'slug' or Page not found (error 404) issue
I'm on Django 2.0, using generic class list view. I have tried dynamic url based on slug and queryset filter on slug to get list of charts by category.
Please help! I've been stuck here for a couple of days since.
views.py
class CategoriesView(generic.ListView):
template_name = 'Bokeh/categories.html'
context_object_name = 'all_categories'
def get_queryset(self):
return Category.objects.all()
class CategorisedListView(generic.ListView):
model = Category
template_name = 'categories/list_of_charts_by_category.html'
context_object_name = 'categorised'
def get_queryset(self):
self.category = get_object_or_404(Category, name = self.kwargs['slug'])
return Chart.objects.filter(category=self.slug)
models.py
class Category(models.Model):
name = models.CharField(max_length=100)
image_file = models.ImageField(default=None, unique=True)
slug = models.SlugField(max_length=100, unique=True)
parent = models.ForeignKey('self', on_delete=models.PROTECT, blank=True, null=True, related_name='children')
def __str__(self):
return self.name
def get_absolute_url(self):
return '{slug}/'.format(slug=self.slug)
class Meta:
ordering = ('name',)
verbose_name = 'Category'
verbose_name_plural = 'Categories'
class Chart(models.Model):
name = models.CharField(max_length=250)
slug = models.SlugField(max_length=250, unique=True)
description = models.TextField(max_length=250)
url = models.URLField(default=None, blank=True)
embed_url = models.TextField(default=None, blank=True)
image_file = models.ImageField(default=None, unique=True)
code_file = models.FileField(default=None, blank=True, unique=True)
chart_library = models.CharField(max_length=250)
author = models.ForeignKey(User, on_delete=models.CASCADE, default=1)
tag = TaggableManager()
category = models.ForeignKey(Category, on_delete=models.CASCADE, blank=True, null=True)
def __str__(self):
return self.name + ' - ' + self.chart_library
def get_absolute_url(self):
return reverse('Bokeh:detail', kwargs={'pk': self.pk})
def read_file(self):
data = self.code_file.path
with open(self.code_file.path, 'r', encoding='UTF-8') as data:
content = data.read()
return content
class Meta:
ordering = ('name',)
urls.py
path("categories/", views.CategoriesView.as_view(), name='categories'),
# /Bokeh/categories/<category_slug>
path("categories/<slug:slug>/", views.CategorisedListView.as_view(), name='list_of_charts_by_category'),
it is supposed to query the database when a specific category is clicked and return the list of charts categorised under that specific category. However, the page throws 'CategorisedListView' object has no attribute 'slug'
The lookup you're doing in get_queryset() isn't quite right. Firstly, you seem to be looking up the Category by name rather than by the slug. Then you try and filter the Charts using their category attribute, but instead of passing the category you pass a non-existent attribute self.slug.
Try changing the implementation to this:
def get_queryset(self):
# Lookup the Category using it's slug attribute, not name, and assign to local variable
category = get_object_or_404(Category, slug=self.kwargs['slug'])
# Now lookup the Charts using the category we just looked up
return Chart.objects.filter(category=category)

Categories