Make the number of rows after narrowing-down - python

This is my serializer.
class MixSerializer(serializers.ModelSerializer):
pub_date = serializers.DateTimeField(format="%m/%d/%Y,%I:%M:%S %p")
new_order = #I want to get the number order
class Meta:
model = Mix
fields = ('id','pub_date','detail','user','u_key')
And I narrowing-down the rows like this below.
def get_queryset(self):
queryset = Mix.objects.all()
u_key = self.request.query_params.get('u_key')
if u_key is not None:
queryset = queryset.filter(u_key=u_key)
return queryset
For example, it returns the 30 items from 100 items.
so id should be (1,4,5,6,9,11,13...) like this,
However I want to get the number new_order (1,2,3,4,5,6,....)
I guess I should do some trick in Serializer?
or any other way ?
Any help appreciated.

Well ID is the actual ID in the database, which you don't want to change or override in your queryset (or elsewhere such as your template) because then you would be referring to a different model object, which will cause you problems.
If you want to use ID as some sort of ranking then you have some options, referencing my answer here
The easiest way is to use the forloop.counter in a template or enumerate in a view:
# template
{% for object in objects %}
# rank is {{ forloop0.counter }}
{% endfor %}
# views
for index, value in enumerate(queryset):
# order is the index variable
...
If you want to explicitly add the rank to the queryset then you can use annotation:
from django.db.models import Window, F
from django.db.models.functions import DenseRank
queryset = Mix.objects.annotate(
ranking=Window(
expression=DenseRank(),
order_by=[
F('id').desc(),
]))

If you want to get Order Table data, you have to create an Order Serializer and link to this MixSerilizer, Like this,
class OrderSerializer(serializers.ModelSerializer):
class Meta:
model = Order
fields = ('id',)
class MixSerializer(serializers.ModelSerializer):
pub_date = serializers.DateTimeField(format="%m/%d/%Y,%I:%M:%S %p")
new_order = OrderSerializer()
class Meta:
model = Mix
fields = ('id','pub_date','detail','user','u_key','new_order')
models.py
class Mix(models.Model):
----
----
order = models.ForeignKey(Order, related_name=new_order, on_delete=models.CASCADE)
If want to get parent table data into a child table you have to pass "related_name" attribute in a models fields. and also that name in a child table sterilizer.

Related

How to pass a variable to class based views (ListView)

My Views.py code
class ListaFuncionariosView(ListView):
model = Funcionarios
template_name = '../templates/funcionarios/lista_funcionarios.html'
paginate_by = 10
ordering = ['FuncionarioCartao']
queryset = Funcionarios.objects.filter(EmpresaCodigo=1)
funcionarios_number = Funcionarios.objects.aggregate(Count('FuncionarioCartao'))
My HTML
<h1>Good Morning</h1>
Exists: {{funcionarios_number}}
<br>
{{funcionarios}}
I would like to show the total number of registered employees in my db table (in the HTML file below), but I don't know how to put variables in class based views, in this case ListView. I'm using 4.0 Django
I tried put: funcionarios_number = Funcionarios.objects.aggregate(Count('FuncionarioCartao')) in bellow of my class, but this is not showed in my html.
By aggregating at the class-level, the query will run when you start the server, and the count will thus always remain that exact number.
You can define this in a function:
class ListaFuncionariosView(ListView):
model = Funcionarios
template_name = '../templates/funcionarios/lista_funcionarios.html'
paginate_by = 10
ordering = ['FuncionarioCartao']
queryset = Funcionarios.objects.filter(EmpresaCodigo=1)
def funcionarios_number(self):
return Funcionarios.objects.aggregate(total=Count('FuncionarioCartao'))[
'total'
]
and then access the function in the view in the template:
{{ view.functionarios_number }}

How to serialize an array of objects in Django

I am working with Django and REST Framework and I am trying to create a get function for one of my Views and running into an error. The basic idea is that I am creating a market which can have multiple shops. For each shop there can be many products. So, I am trying to query all those products which exist in one shop. Once I get all those products I want to send it to my serializer which will finally return it as a JSON object. I have been able to make it work for one product but it does not work for an array of products.
My Product model looks like this:
'''Product model to store the details of all the products'''
class Product(models.Model):
# Define the fields of the product model
name = models.CharField(max_length=100)
price = models.IntegerField(default=0)
quantity = models.IntegerField(default=0)
description = models.CharField(max_length=200, default='', null=True, blank=True)
image = models.ImageField(upload_to='uploads/images/products')
category = models.ForeignKey(Category, on_delete=models.CASCADE, default=1) # Foriegn key with Category Model
store = models.ForeignKey(Store, on_delete=models.CASCADE, default=1)
''' Filter functions for the product model '''
# Create a static method to retrieve all products from the database
#staticmethod
def get_all_products():
# Return all products
return Product.objects.all()
# Filter the data by store ID:
#staticmethod
def get_all_products_by_store(store_id):
# Check if store ID was passed
if store_id:
return Product.objects.filter(store=store_id)
The product serializer that I built is as follows:-
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = '__all__'
and the view that I created is below
class StoreView(generics.ListAPIView):
"""Store view which returns the store data as a Json file.
"""
# Define class variables
serializer_class = StoreSerializer
# Manage a get request
def get(self, request):
# Get storeid for filtering from the page
store_id = request.GET.get('id')
if store_id:
queryset = Product.get_all_products_by_store(store_id)
# queryset = Product.get_all_products_by_store(store_id)[0]
else:
queryset = Product.get_all_products()
# queryset = Product.get_all_products()[0]
print("QUERYSET", queryset)
return Response(ProductSerializer(queryset).data)
The above view gives me the following error
AttributeError at /market
Got AttributeError when attempting to get a value for field `name` on serializer `ProductSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `QuerySet` instance.
Original exception text was: 'QuerySet' object has no attribute 'name'.
If instead queryset = Product.get_all_products_by_store(store_id), I use the line below it where I am only selecting the first option then I get the correct JSON response but if there multiple products then I am not able to serialize. How do I make it work?
If you want to serialize more than one record, either use ListSerializer instead, or pass many=True the the constructor of ModelSerializer:
return Response(ProductSerializer(queryset, many=True).data)
I found the answer thanks to #yedpodtrzitko for giving the direction.
I had to make two changes.
Define queryset outside the function
Pass many=True the the constructor of ModelSerializer
class StoreView(generics.ListAPIView):
"""Store view which returns the store data as a Json file.
"""
# Define class variables
queryset = []
serializer_class = StoreSerializer
# Manage a get request
def get(self, request):
# Get storeid for filtering from the page
store_id = request.GET.get('id')
if store_id:
queryset = Product.get_all_products_by_store(store_id)
else:
queryset = Product.get_all_products()
print("QUERYSET", queryset)
return Response(ProductSerializer(queryset, many = True).data)

Not expected django query set response

I'm making a query set with django to list some courses. The problem is when I make the query in the django shell, it returns something like this: <QuerySet [<Course: Course object (1)>,....]>
How can I make it to obtain the table information?
PSD: I make a query set with the users table exactly as I described and I get the expected result. But it can't show the result in the template. So if you can help... Thanks for the help in advance.
class ListCursos( TemplateView):
model1 = User
model2 = Course
template_name = 'plantillas/miscursos.html'
def get_context_data(self, *args, **kwargs):
context = super(ListCursos, self).get_context_data(**kwargs)
context['usuarios'] = User.objects.all()
context['cursos'] = Course.objects.all()
return context
The values of the columns for each instance of a model are as stored as instances variables. You have not provided the definition of one of your models, so I'll just take this for an example.
class Course(models.Model): # example model
name = models.CharField(max_length=10)
students = models.IntegerField()
When you have a queryset of Course models you can access them by index
>>> all_courses = Course.objects.all()
<QuerySet [<Course: Course object (1)>]>
>>> first_course = all_courses[0]
and to acess the values of the selected Course model instance you just type the names for the columns that you have in the class definition. if for example you have the Course model with name history and 10 students then
>>> first_course.name # just type the name of the column
'history'
>>> first_course.students
10
So to access them in a django template, considering that you are passing in the context the Course.objects.all() with a key of "cursos". (like you are doing)
{% for course in cursos %}
<div>{{course.name}}</div>
<div>{{course.students}}</div>
{% endfor %}

Sum of fields for filtered queryset using django_filters

I have the following view
class AuthorList(FilterView):
model = Author
filterset_class = AuthorFilter
context_object_name = 'authors'
In the template, one of the field is {{ author.value }}, which is an integer.
What I would like to do is to show the sum of all {{ author.value }} in my template, but in a dynamic way (if some filters are used, the sum is updated with the current Queryset).
I have tried adding extra context with get_context_data but I couldn't find out how to make it in a dynamic way.
EDIT
tried this, still not working:
#property
def get_sum_values(self):
sum_values = self.objects.all().aggregate(Sum('value'))['value__sum']
return sum_values
and in the template: {{ authors.get_sum_values }}
I have also tried to add a print statement in the property, but nothing shows up, so I guess the function is not even loaded.
my models:
class Author(models.Model):
name = models.CharField(max_length=50, blank=True, null=True)
value = models.IntegerField(null=True, blank=True)
Have you tried doing the sum in the model as a function ?
#property
def wallet_amount_guests(self):
data_payments = self.user.earnings_set.filter(transaction_type='g').aggregate(Sum('amount'))['amount__sum']
if data_payments == None:
data_payments = 0
return data_payments
The above is just an example I have used before. You can then call in the html as blah.function_name

Django - filtering on foreign key

I have a problem about filter in django. Please help me. I want to display the objects of the product which has different categories when I click on l.category_name
my html (CategoryList.html):
{% for l in forms %}
<h2>{{ l.category_name }}</h2>
{% endfor %}
CategoryView.html
{{get_product.product_name}}
my model:
class Category(models.Model):
category_id = models.AutoField(primary_key = True)
category_name = models.CharField(max_length = 20)
def __unicode__(self):
return self.category_name
class Product(models.Model):
product_id = models.AutoField(primary_key = True)
product_name = models.CharField(max_length = 50)
product_category = models.ForeignKey(Category)
product_color = models.CharField(max_length = 30)
def __unicode__(self):
return self.product_name
my view:
def category_list(request):
list = Category.objects.all()
context = {'forms':list}
return render(request,'webpage/CategoryList.html',context)
def category_view(request,category_id):
all = Product.objects.all()
if request.POST:
get_id = Category.objects.get(category_id = request.POST['category_id'])
get_category = Product.objects.get(product_category =
request.POST['product_category'])
get_category.product_category = get_id
get_category.save()
if get_category:
get_product = Product.objects.filter(product_category__category_name =
request.POST['category_name'])
context = {'get_product':get_product}
return render(request,'webpage/CategoryView.html',context)
I read document in https://docs.djangoproject.com/en/1.6/topics/db/queries/ but i don't understand .I know i was wrong category_view
There seem to be a lot of problems with your code.
First, you don't have to declare ids in your code. Django does that automatically for you. So, categor_id and product_id are unnecessary.
Second,
Remove the .POST check. You aren't posting anything.
Third,
get_id = Category.objects.get(category_id = request.POST['category_id']) # returns a category, not an id
get_category = Product.objects.get(product_category =
request.POST['product_category']) # returns the product list, not a category
get_category.product_category = get_id
is the same as
category = Category.objects.get(category_id = request.POST['category_id'])
product_list = Product.objects.get(product_category = category)
Fourth, don't hardcode URLs in your template. Use the {% url %} tag instead.
Finally,
You can then pass this product_list to the template
context = {'product_list':product_list}
return render(request,'webpage/CategoryView.html',context)
The way foreign keys are stored is through automatic fields(IDs). Since 'Category' is a foreign field of 'Product', when you make a record entry, the id of category is stored in 'product_category' field in products table.
I think your code is a little confusing since you are trying to do somethings django does automatically for you. Like, once you define a foreign key, the id of the foreign key table record is stored automatically, you don't have to get the id of 'category' entry and store it in products table entry.
What you are trying to achieve is simple, lets say you have the category_name and nothing else, get the id of the category table entry,
category_object = Category.objects.get(category_name = category_name)
category_id = category_object .id
If you already have the ID of category, then you can skip the above step, and simply use the ID to query the products table to get the needed records
Product.objects.filter(product_category = category_id)
In your templates, you can iterate through these product records and display whatever is needed.
BTW, use the .update() method to update any fields instead of save() method.
Something like this:
Entry.objects.all().update(blog=b)
It will be well worth your time reading through the queries help.
Django queries

Categories