Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

239
Views
cómo convertir la salida de Count() en django a FloatField en django 1.8

Estoy usando django 1.8.

Tengo dos modelos:-

 class Query(models.Model): user = models.ForeignKey(settings.AUTH_USER_MODEL) title = models.TextField() details = models.TextField() pub_date = models.DateTimeField('date published') post_score=models.FloatField(default=0.0) .... class Tags(models.Model): """docstring for Tags""" tagname=models.TextField() grouppostlist=models.ManyToManyField(Query,through='GroupPostsTag',through_fields=('tag','query')) # and another model(it stores tags for a query) class GroupPostsTag(models.Model): query=models.ForeignKey('Query') tag=models.models.ForeignKey('Tags')

Ahora quiero ordenar las consultas según la suma de "número de etiquetas" y "post_score" de la consulta. Estoy buscando algo como esto: -

 tagged_user_posts = Query.objects.filter(Q(tags__id__in=tags_list)).annotate(num_tags=Cast(Count('tags'),models.FloatField())).annotate(post_scores=F('num_tags')+F('post_score')).order_by('-post_scores')

Cast se proporciona en Django 1.10. Entonces, ¿qué alternativa puedo usar?

about 4 years ago · Santiago Trujillo
3 answers
Answer question

0

Como dije en mi comentario, simplemente puede copiar el código fuente de la clase Cast y guardarlo en sus proyectos y usarlo.

Resulta que no fue tan simple como eso . También deberá cambiar Cast.as_sql como está en v1.10 . Y no es necesario hacer una super llamada a Func.as_sql .

Simplemente copie el siguiente código y guárdelo en su proyecto. Lo he probado y funciona.

 from django.db.models import Func, fields class Cast(Func): """ Coerce an expression to a new field type. """ function = 'CAST' template = '%(function)s(%(expressions)s AS %(db_type)s)' mysql_types = { fields.CharField: 'char', fields.IntegerField: 'signed integer', fields.FloatField: 'signed', } def __init__(self, expression, output_field): super(Cast, self).__init__(expression, output_field=output_field) def as_sql(self, compiler, connection, function=None, template=None, arg_joiner=None, **extra_context): if 'db_type' not in extra_context: extra_context['db_type'] = self._output_field.db_type(connection) connection.ops.check_expression_support(self) sql_parts = [] params = [] for arg in self.source_expressions: arg_sql, arg_params = compiler.compile(arg) sql_parts.append(arg_sql) params.extend(arg_params) data = self.extra.copy() data.update(**extra_context) # Use the first supplied value in this order: the parameter to this # method, a value supplied in __init__()'s **extra (the value in # `data`), or the value defined on the class. if function is not None: data['function'] = function else: data.setdefault('function', self.function) template = template or data.get('template', self.template) arg_joiner = arg_joiner or data.get('arg_joiner', self.arg_joiner) data['expressions'] = data['field'] = arg_joiner.join(sql_parts) return template % data, params def as_mysql(self, compiler, connection): extra_context = {} output_field_class = type(self._output_field) if output_field_class in self.mysql_types: extra_context['db_type'] = self.mysql_types[output_field_class] return self.as_sql(compiler, connection, **extra_context) def as_postgresql(self, compiler, connection): # CAST would be valid too, but the :: shortcut syntax is more readable. return self.as_sql(compiler, connection, template='%(expressions)s::%(db_type)s')
about 4 years ago · Santiago Trujillo Report

0

Como mencionó en la pregunta para django 1.10, puede usar la función Cast incorporada. Para versiones anteriores, puede usar la expresión Func()

 from django.db.models import Count, Func, F, ExpressionWrapper, FloatField tagged_user_posts = Query.objects.filter(Q(tags__id__in=tags_list)). annotate(num_tags=Func(Count('tags'), template='%(function)s(%(expressions)s AS %(type)s)', function='Cast', type='float') ). annotate(post_scores=ExpressionWrapper(F('num_tags')+F('post_score'), output_field=FloatField())). order_by('-post_scores')
about 4 years ago · Santiago Trujillo Report

0

Podrías definir Cast como

 def Cast(what, as_type): if isinstance(as_type, Field): as_type = as_type.db_type(connection) return Func( what, template='%(function)s(%(expressions)s AS %(type)s)', function='Cast', type=as_type, )
about 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!