Django Haystack faceting on the model type - django-haystack

I want to facet the results based on the different model_names (classes) returned. Is there an easy way to do this?

Have you tried adding a SearchIndex field with this information? E.g.
class NoteIndex(SearchIndex, indexes.Indexable):
title = CharField(model_attr='title')
facet_model_name = CharField(faceted=True)
def get_model(self):
return Note
def prepare_facet_model_name(self, obj):
return "note"
class MemoIndex(SearchIndex, indexes.Indexable):
title = CharField(model_attr='title')
facet_model_name = CharField(faceted=True)
def get_model(self):
return Memo
def prepare_facet_model_name(self, obj):
return "memo"
And so on, simply returning a different string for each search index. You could also create a mixin and return the name of the model returned by get_model too.
Presuming you've added this field to each of your SearchIndex definitions, just chain the facet method to your results.
results = form.search().facet('facet_model_name')
Now the facet_counts method will return a dictionary with the faceted fields and count of results for each facet value, in this case, the model names.
Note that the field here is labeled verbosely to avoid a possible conflict with model_name, a field added by Haystack. It's not faceted, and I'm not sure if duplicating it will cause a conflict.

If you just want to filter on the model type, you can use the ModelSearchForm

The Docs have a really good walk-through for this.
The minimum you'll need:
is to add faceted=True to the params of your model_names field.
Rebuild your schema and indices.
add .facet('model_names') to whatever SearchQuerySet you're wanting to facet.
More explanation on the question would enable a more complete answer.

Related

manyone field with my own default value, Odoo

I have the sale.order model which has the partner_shipping_id.country_id field of the res.country model, what I want is to know how to have a new many2one field (res.country) but that has the sale_order.partner_shipping_id.country_id field loaded by default .
I have tried two ways without being able to get the result:
def _default_country_edit(self):
return self.partner_shipping_id.country_id
country_edit = fields.Many2one('res.country', string="País", default=lambda self: self._default_country_edit())
or:
country_edit = fields.Many2one('res.country', string="País", default=_default_country_edit())
I need something like this:
What I did is in the read method, if you don't have the new field set it and that's it
if not self.country_edit:
self.country_edit = self.partner_shipping_id.country_id
Obviously, in the write method, the sale_order.partner_shipping_id.country_id field must be set with the new one.

Sorting custom columns with django-datatables-view

Using Django 3, python 3.6, django-datatable-view 1.19.1
Trying to do a datatable with columns from my model and computed before output ones.
I draw all values that I needed but after trying to sort custom column getting an error:
Cannot resolve keyword 'XXXX' into field. Choices are: ...
I've found a way to register a column as virtual column, without db source, but it was in django-datatable-view 0.5.4 docs but those ways don't work anymore. In last version documentation links with info that I need are unavailable.
Please, help me to figure out, how can I deal with custom computed columns from my model's fields( sort, render )
This is a little tricky now.
To define computed fields:
class ListJson(BaseDatatableView):
columns = ["id", "status_code", "computed_field"]
order_columns = ["id", "status_code"]
# Override render_column method
def render_column(self, row, column):
if column == "computed_field":
return row.computed_field()
else:
return super(ListJson, self).render_column(row, column)
This allows you to return the computed_field method value().
The situation becomes complicated when we want to sort on calculated fields. In this case, it is best to disable serverSide operations in JavaScript
$.extend($.fn.dataTable.defaults, {
serverSide: false,
});
However, you will then have to return all the lines at once, which can kill the server.
If you want to sort on the backend side, you need to arrange and return the appropriate queryset with a virtual field.
class ListJson(BaseDatatableView):
def get_initial_queryset(self):
return qs
Just build your query like THIS.

Django Rest Framework: Why does PrimaryKeyRelatedField document as a string in the schema when read_only?

I have a serializer with a PrimaryKeyRelatedField:
field_name = serializers.PrimaryKeyRelatedField(queryset=ModelClass.objects.all(), read_only=False)
With this setup, the Schema properly identifies the parameter as an integer (the PK). But, when I change to:
field_name = serializers.PrimaryKeyRelatedField(read_only=True)
(it will not let you specify queryset and read_only at the same time) then the parameter is identified as a string in the Schema.
Why would this be? Is this correct/expected behavior or perhaps a bug?
Well, I had banged my head on this one long enough to post on SO, but as I've continued to dig into it I think I am making some progress.
At rest_framework/schemas/openapi.py:380 inside of map_field() you find the following:
if isinstance(field, serializers.PrimaryKeyRelatedField):
model = getattr(field.queryset, 'model', None)
if model is not None:
model_field = model._meta.pk
if isinstance(model_field, models.AutoField):
return {'type': 'integer'}
RelatedField won't let you specify a queryset when read_only=True though, so then the "model" in the above code snippet is always None when read_only=True, and you end up getting type="string" at the bottom of the map_field function.
So this explains why it is currently happening, and seems like a bug in DRF, but now I guess I just need to look into what the appropriate fix would be.
I've opened up a corresponding issue against DRF: https://github.com/encode/django-rest-framework/issues/7427

Django Queryset Values of Children and Parent

I am looking for a way to retrieve a parent field during a query of the the children records. At this time I have the following example model.
class Record(models.Model):
event_title=models.CharField(max_length=500)
event_description=models.CharField(max_length=4000)
class SecondTable(models.Model):
event_code=models.ForeignKey(Record, default=0, on_delete=models.CASCADE)
wasfun=models.BoolField(default=True)
When I view the values of the queryset and select_related below, the values from the parent don't seem to be included (i.e. event_description). However, the .query property shows all the fields being selected.
SecondTable.objects.all().select_related("event_code").values()
Is there a way to see all values from the joined tables? Sorry for a newbie question. Thanks!
I think not in only one line, but you can try with next:
values_second_table = [s.name for s in SecondTable._meta.fields]
values_first_table = ['event_code__{}'.format(r.name) for r in Record._meta.fields]
my_values = values_second_table + values_first_table
SecondTable.objects.all().select_related("event_code").values(*my_values)

adding reserved lot name in sale.order.line in odoov10

I would like to write small module that inherit sale.order.line and adding reserved lot on sale order line tree view.
under the sale.order.line module, there is the field name move_ids (stock.move , one2many) fields. I would like to create move_ids.move_line_ids.lot_id
So I tried the following code:
lot_name = fields.Char(related="move_ids.move_line_ids.lot_id", string="String")
but no luck and saw internal server error.
jooze
You can not do that, type of related field lot_name is inconsistent with lot_id.
Try to use a computed Many2many field to get all lot ids related to the current record.
Edit:
class SaleOrderLine(models.Model):
_inherit = 'sale.order.line'
lot_ids = fields.Many2many('stock.production.lot', compute='_get_lot_ids')
#api.one
#api.depends('move_ids.move_line_ids.lot_id')
def _get_lot_ids(self):
# returns the union of all lots, with duplicates removed
self.lot_ids = self.mapped('move_ids.move_line_ids.lot_id')

Resources