Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add way to figure out the model in the template for composite searches and linking to the results #114

Open
GoogleCodeExporter opened this issue Mar 16, 2015 · 16 comments

Comments

@GoogleCodeExporter
Copy link

Currently there is no "easy" way to figure out the model for the hit in the 
template. 
hit.model returns the model object, not the class for it.

Original issue reported on code.google.com by hvdkl...@gmail.com on 11 Jun 2010 at 11:51

@GoogleCodeExporter
Copy link
Author

Having a `hit.model' object one could use generic Python introspection:

    from <project>.<application>.models import MyModel, MyAnotherModel
    ...

    indexers = [MyModel.indexer, MyAnotherModel.indexer]
    indexer CompositeIndexer(*indexers)
    for hit in indexer.search("search terms"):
        if isinstance(hit.model, MyModel):
            # do something
    ...

There's also Django's Options class instance `hit.model._meta` which has 
`app_label` and `db_table` attributes among others (see 
http://docs.djangoproject.com/en/dev/ref/models/options/#available-meta-options)

Original comment by esizi...@gmail.com on 21 Jun 2010 at 3:09

@GoogleCodeExporter
Copy link
Author

Original comment by daevaorn on 21 Jun 2010 at 3:43

  • Added labels: Type-Enhancement
  • Removed labels: Type-Defect

@GoogleCodeExporter
Copy link
Author

You're not allowed to access _ attributes in the template.
And looping through everything twice doesn't make sense.

Now I'm searching users and forum posts. The results should link to totally 
different things. get_absolute_url is nice but kinda evil and unusable for the 
forum posts.

so I just want to be able to check the app_name and model_name without having 
to write a whole templatetag for it. Either add them as properties to the hit 
class or add a template tag to get them from a hit.

Original comment by hvdkl...@gmail.com on 22 Jun 2010 at 11:56

@GoogleCodeExporter
Copy link
Author

I think we add `model_name` attribute to hit object.`````

Original comment by daevaorn on 22 Jun 2010 at 12:36

  • Changed state: Accepted
  • Added labels: Milestone-Release2.5

@GoogleCodeExporter
Copy link
Author

I'll be needing this pretty soon for a big project. If it's not in by then I'll 
probably write a patch myself. If I do I'll post it here.

Original comment by hvdkl...@gmail.com on 23 Jun 2010 at 8:49

@GoogleCodeExporter
Copy link
Author

I would suggest to go with a templatetag.

How do you usually get a `model_name` for a standard Django QuerySet results 
item?

Original comment by esizi...@gmail.com on 24 Jun 2010 at 7:18

@GoogleCodeExporter
Copy link
Author

What I did now to quickly overcome the problem is this:

@register.filter
def get_model_from_hit(hit):
  """
    Returns the `app_label.model_name` for the hit
  """
  content_type = ContentType.objects.get_for_model(hit.model)
  return "%s.%s" % (content_type.app_label, content_type.model)



Original comment by hvdkl...@gmail.com on 24 Jun 2010 at 7:29

@GoogleCodeExporter
Copy link
Author

Having a filter is exactly the stadard way how to get Django model's options ;)

I would not use ContentType here as it will make addition hit into the database.
Please consider the code below.


from django import template
from django.template.defaultfilters import stringfilter

register = template.Library()

@register.filter
@stringfilter
def get_model_from_hit(hit):
  """
    Returns the `app_label.model_name` for the hit
  """
  opts = hit.model._meta
  return "%s.%s" % (opts.app_label, opts.module_name) # there is also opts.object_name which is the exact model's class name like `MyCoolModel`
get_model_from_hit.is_safe = True

Original comment by esizi...@gmail.com on 24 Jun 2010 at 7:45

@GoogleCodeExporter
Copy link
Author

ContentTypes are cached.. as long as the server is running it hits the database 
only once ;-)

But yeah.. your method would be better :)

Original comment by hvdkl...@gmail.com on 24 Jun 2010 at 7:57

@GoogleCodeExporter
Copy link
Author

Oh.. and you don't want the string filter thing. It converts all the input to 
unicode, which the hit isn't :)

Original comment by hvdkl...@gmail.com on 24 Jun 2010 at 7:59

@GoogleCodeExporter
Copy link
Author

Yep, @stringfilter is not need here - I copy-pasted the decorators from another 
filter ;)

Original comment by esizi...@gmail.com on 24 Jun 2010 at 8:02

@GoogleCodeExporter
Copy link
Author

So the final version is:

from django import template

register = template.Library()

@register.filter
def get_model_from_hit(hit):
  """
    Returns the `app_label.model_name` for the hit
  """
  opts = hit.model._meta
  return "%s.%s" % (opts.app_label, opts.module_name)
get_model_from_hit.is_safe = True

Original comment by esizi...@gmail.com on 24 Jun 2010 at 8:13

@GoogleCodeExporter
Copy link
Author

I think this filter can be more generalized (accepts model itself not `hit` 
instance) and ships separately.

Close ticket?

Original comment by daevaorn on 24 Jun 2010 at 12:54

@GoogleCodeExporter
Copy link
Author

I'd vote for not making this a part of Djapian, and closing the issue as 
"WontFix"

Original comment by esizi...@gmail.com on 25 Jun 2010 at 5:30

@GoogleCodeExporter
Copy link
Author

I think it should be part of djapian. You will need this in every 
CompositeIndex template because you otherwise don't know where to link the 
result to.

Original comment by hvdkl...@gmail.com on 25 Jun 2010 at 6:38

@GoogleCodeExporter
Copy link
Author

The usage of search results is an application domain. The filter above is just 
an example. Having a "app_label.model_name" string wouldn't help a lot for 
"linking". You could use {{{hit.instance.get_get_absolute_url}}} in your 
template to get a public link to the result hit instance whatever "type" it has.

Original comment by esizi...@gmail.com on 30 Jun 2010 at 6:25

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant