I'm trying to get unique results from s query_set.
Example.
ID | NOMBRE | CLASIFICACION
1 Escoba Limpieza
2 Trapeador Limpieza
3 Tornillo Herramienta
I want to get "Limpieza and Herramienta" only. currently I'm getting "Limpieza, Limpieza and Herramineta"
my views.py:
class ItemListView(ListView):
model= Items
def get_context_data(self,**kwargs):
context = super(ItemListView, self).get_context_data(**kwargs)
context['clasificacion'] =Items.objects.order_by('nombre').distinct('clasificacion')
return context
my models.py
from django.db import models
# Create your models here.
class Items(models.Model):
nombre = models.CharField(max_length=250)
descripcion = models.CharField(max_length=250)
codigo_proveedor = models.CharField(max_length=250)
clasificacion = models.CharField(max_length=250)
c_minima = models.IntegerField()
c_actual = models.IntegerField()
proveedor = models.ForeignKey('Proveedores',on_delete=models.CASCADE)
active = models.BooleanField()
def __str__(self):
return self.nombre + ' ----- ' +
self.clasificacion + ' ----- ' +
str(self.c_actual)
class Proveedores(models.Model):
nombre = models.CharField(max_length=250)
telefono = models.CharField(max_length=250)
direccion1 = models.CharField(max_length=250)
direccion2 = models.CharField(max_length=250, null=True)
active = models.BooleanField()
def __str__(self):
return self.nombre
Thanks for the help!
Will's response is correct, but I think you want to do the order_by() operation first to ensure you are getting the correct results.
context['clasificacion'] =(Items
.objects
.order_by('clasification', 'nombre')
.distinct('clasificacion'))
context['clasificacion'] = Items.objects.order_by('clasificacion', 'nombre').distinct('clasificacion')
distinct() must match the leftmost order_by(). So making the column you use in distinct() the first column in the order_by() makes it work.
Related
This is my model:
class Car(models.Model):
make = models.CharField(max_length=30)
model = models.CharField(max_length=30)
rating = models.PositiveIntegerField(validators=[MinValueValidator(1), MaxValueValidator(5)], default=0, blank=True)
avg_rating = models.FloatField(default=0, blank=True)
rates_number = models.IntegerField(default=0, blank=True)
def __str__(self):
return self.make + ' ' + self.model
What's the best way to move the logic from the following perform_create function (in views.py) to my models?
class CarRate(generics.CreateAPIView):
serializer_class = CarRatingSerializer
queryset = Car.objects.all()
def perform_create(self, serializer):
pk = serializer.validated_data['car_id']
rating = serializer.validated_data['rating']
queryset = Car.objects.all()
car_queryset = get_object_or_404(queryset, pk=pk)
if car_queryset.rates_number == 0:
car_queryset.avg_rating = rating
else:
car_queryset.avg_rating = (car_queryset.avg_rating + rating)/2
car_queryset.avg_rating = round(car_queryset.avg_rating, 1)
car_queryset.rates_number = car_queryset.rates_number + 1
car_queryset.save()
It would be much better to create two models. Think about how you are counting average rating. This would be some better idea for now:
class Car(models.Model):
make = models.CharField(max_length=30)
model = models.CharField(max_length=30)
def rates_number(self):
return self.rates.all().count()
def avg_rating(self):
# count average_rating from relation to Rate objects and return it
return average_rating
class CarRate(models.Model):
value = models.PositiveIntegerField(validators=[MinValueValidator(1), MaxValueValidator(5)], default=0, blank=True)
car = models.ForeignKey(Car, on_delete=models.CASCADE, related_name='rates')
I would like to filter my plots objects on the fruit ex.pear. The Inputs are linked via a manytomany to the plots. This is the structure:
This is the data I get out of it:
What i would like to have:
result:
I tried the following:
plots = Plot.objects.filter(fruittype__fruit="Pear")
inputs = Input.objects.filter(plot__in=plots).distinct()
This gives me already a close solution for my problem but not what I want.
Now I only would like to filter out the other plots that still show up with apple.
models inputs:
class Product (models.Model):
type = models.ForeignKey(Type, on_delete=models.CASCADE)
product = models.CharField(max_length=70)
standaard_dosis = models.FloatField()
def __str__(self):
return self.product
class Input (models.Model):
datum = models.DateField()
plot = models.ManyToManyField(Plot)
def __str__(self):
return str(self.datum)
class ProductInputs (models.Model):
input = models.ForeignKey(Inputs, on_delete=models.CASCADE, default="")
product = models.ForeignKey(Product, on_delete=models.CASCADE, default="")
dosis = models.FloatField()
def __str__(self):
string = str(self.product)
return string
models plots:
class Fruit(models.Model):
fruit = models.CharField(max_length=30, primary_key=True)
def __str__(self):
return self.fruit
class Meta:
verbose_name_plural = "fruits"
class Fruittype(models.Model):
fruit = models.ForeignKey(Fruit, on_delete=models.CASCADE)
fruittype = models.CharField(max_length=30, primary_key=True)
def __str__(self):
return self.fruittype
class Meta:
verbose_name_plural = "fruitypes"
class Plot(models.Model):
name = models.CharField(max_length=30)
fruittype = models.ForeignKey(Fruittype, on_delete=models.CASCADE)
def __str__(self):
return str(self.fruittype.fruit) + " | " + self.name
class Meta:
verbose_name_plural = "plots"
Your Plot queryset is not going as deep as it should. I think you should change to something like this (although this is it's a bit of overkill)
plot_ids = Plot.objects.filter(fruittype__fruit__fruit="Pear").values_list('pk', flat=True)
or
plot_ids = Plot.objects.filter(fruittype__fruittype="Pear").values_list('pk', flat=True) # I don't know what fruittype is but I guess this would help you
Then your "inputs"
inputs = Input.objects.filter(plot__pk__in=plot_ids).distinct()
You might wanna try this as well:
from django.db.models import Prefetch
Input.objects.prefetch_related(
Prefetch('plot', queryset=Plot.objects.filter(fruittype__fruit__fruit="Pear"))
)
It worked with:
all_inputs=Input.objects.filter(plot__pk__in=plot_ids).distinct().prefetch_related(Prefetch('plot', queryset=Plot.objects.filter(fruittype__fruit__fruit="Pear")))
I'm trying to get the number of products that have each category, but each category is in turn parent of other categories, so I want to know how many children have that category and their daughter categories, I have simplified the query to the maximum in the following way, but in the django debug I keep showing that I have 66 querys duplicates.
How can I eliminate these duplications?
With the first line of views.py, he managed to get the number of products in a category, but the problem is essentially to tell him to return me from the category and his daughters.
models.py
class Categoria(models.Model):
nombre = models.CharField(max_length=200)
slug = models.SlugField(max_length=100)
padre = models.ForeignKey('self', blank=True, null=True,
related_name='cat_padre')
pub_date = models.DateTimeField('date published',
auto_now_add=True)
upd_date = models.DateTimeField('date updated', auto_now=True)
def __str__(self):
return self.nombre + ' ' + self.pais.iso
class Producto(models.Model):
nombre = models.CharField(max_length=200)
slug = models.SlugField(max_length=100)
categoria = models.ForeignKey(Categoria)
views.py
cats = Categoria.objects.annotate(num_productos=Count('producto')).filter(pais__iso=pais, padre__isnull=True).order_by('-num_productos')
for c in cats:
num_p = Producto.objects.filter(categoria__padre=c).count()
c.num_productos += num_p
contexto = {
'categorias_padre': cats,
}
return render(request, 'web/pruebitas/product.html', contexto)
Django debug:
SELECT COUNT(*) AS "__count" FROM "web_producto" INNER JOIN "web_categoria" ON ("web_producto"."categoria_id" = "web_categoria"."id") WHERE "web_categoria"."padre_id" = '790'
Duplicated 62 times.
Conexión: default
/home/luis/PycharmProjects/lco_web/web/middleware.py in __call__(29)
response = self.get_response(request)
/home/luis/PycharmProjects/lco_web/web/views.py in index(11)
return categoria(request, '', '/')
/home/luis/PycharmProjects/lco_web/web/views.py in categoria(170)
'categorias': categorias(pais, categoria.id if categoria else 0),
/home/luis/PycharmProjects/lco_web/web/views.py in categorias(29)
num_p = Producto.objects.filter(categoria__padre=c).count()
You could achieve this by using reverse lookup to child categories using cat_padre and Count with distinct=True.
cats = Categoria.objects.annotate(
num_productos=Count('cat_padre__producto', distinct=True) +
Count('producto', distinct=True)).filter(
pais__iso=pais, padre__isnull=True).order_by('-num_productos')
P.S. I have tested that on fake data so please compare what you have got earlier with what returns this query.
I am trying to understand how exactly query works on Django, i followed the tutorials it´s not working I am not sure what i am doing wrong.
When I run
BeneficientePagar.objects.filter(nome__contains="Joao Pedro")
it returns
"Choices are %s" %s (name, ",".join(available))) django.core.exceptions.FieldError: Cannot resolve keyword "nome into field. Choices are: ID, beneficiente, beneficiente_id,join, join_id, moeda
from django.db import models
# Create your models here.
class Moeda(models.Model):
moeda_ficticia = models.FloatField()
class Join(models.Model):
nome = models.CharField(max_length=150)
nascimento = models.DateField()
cpf = models.IntegerField(primary_key=True)
endereco = models.CharField(max_length=150)
email = models.EmailField()
def __str__(self):
return self.nome
class Beneficiente(models.Model):
ID = models.AutoField(primary_key=True)
nome = models.CharField(max_length=150)
CNPJ = models.IntegerField(max_length = 10)
def __str__(self):
return self.nome
class Favores(models.Model):
ID = models.AutoField(primary_key=True)
favor = models.CharField(max_length=150)
dataInserido = models.DateField()
usuarios = models.ForeignKey(Join)
def __str__(self):
return self.favor
class BeneficientePagar(models.Model):
ID = models.AutoField(primary_key=True)
moeda = models.IntegerField()
beneficiente = models.ForeignKey(Beneficiente)
join = models.ForeignKey(Join)
def __str__(self):
return self.ID
Thanks in advance
If using BeneficientPager, you need to do
BeneficientePagar.objects.filter(beneficient__nome__contains="Joao Pedro")
You are getting the error because nome is a field on Beneficiente, not BeneficientePagar.
You can either do
Beneficiente.objects.filter(nome__contains="Joao Pedro")
which will return a queryset of Beneficientes. Or if you need BeneficientePagar you can query through the foreign key.
BeneficientePagar.objects.filter(beneficiente__nome__contains="Joao Pedro")
Well i got a problem with Django i want to acces to all the "Reaccion" but add a column (like in the image) if exists a relationship with "ReaccionPost" including "id_post" ,'status', and id_reaccion, but if it's not exist, in the colum should be a 0 por '' and if exists should be 1 or another true statement,
Thank you for reading my issue.
https://drive.google.com/file/d/0B3suBvZgwQ0JVmtxb1pzbmxGZW8/view?usp=sharing
class Reaccion(models.Model):
nombre = models.CharField(max_length=40)
descripcion = models.CharField(max_length=300)
icono = models.CharField(max_length=300)
def __unicode__(self):
return self.nombre
class Post(models.Model):
usuario= models.ForeignKey(User)
tipo= models.ForeignKey(Tipo)
creacion = models.DateTimeField(auto_now_add=True)
status = models.ForeignKey(Estado,default=1)
def __unicode__(self):
return self.titulo
class ReaccionPost(models.Model):
ESTADO = (
(1, 'Activo'),
(2, 'Inactivo'),
)
id_post= models.ForeignKey(Post)
usuario = models.ForeignKey(User)
id_reaccion = models.ForeignKey(Reaccion)
creacion = models.DateTimeField(auto_now_add=True)
status = models.IntegerField(choices=ESTADO,default=1)
def __unicode__(self):
return str(self.usuario) +" "+ str(self.id_post) +" "+ str(self.id_reaccion)