How can I find an image, depending on the text?
I have image model with keywords:
class Post(models.Model):
image = ImageField(_('Image'), blank=True, upload_to='folder')
keywords = models.CharField(_('Keywords'), max_length=80)
And model which will serve as the search for a suitable image
class TextSearch(models.Model):
body = models.TextField(_('Text'))
Are you looking for something like this?
# Set to search for posts with keyword 'cute'
search = TextSearch(body="cute")
# Go run the search
results = Post.objects.filter(keywords__contains=search.body)
This will give you every Post with the TextSearch's body in the keywords. If that's not what you want, you might want to check here for a full list of Django's QuerySet methods.
Related
Hello,
Can some good person give me advice on how to get a queryset of ordered objects by intersecting a many-to-many field with a given one object's many-to-many field?
For example I have:
class Video(models.Model):
tags = models.ManyToManyField(Tag, blank=True)
...
class Tag(models.Model):
name = models.CharField(max_length=64)
...
I select one Video object and would like to have first ten objects that have most similar tags set to show like related videos.
Thanks in advance!
I made a simple example, this should work
tag1 = Tag.objects.create(name="test video") #create a tag
video1 = Video.objects.create() #create a video
video1.tags.add(tag1) #add tag to video
video_query = Video.objects.filter(tags__name="test video")
print("query",video_query)
Now in this example its only 1 tag but if you have 100 tags put [:11] after video_query = Video.objects.filter(tags__name="test video")[:11]
This will give you the exact match.
If you use:
video_query = Video.objects.filter(tags__in=example_video.tags.all())
You will get a query with all the videos with at least 1 matching tag, if a video has 2 matching tags it will be present 2 times in the query. You can fetch the videos which are present multiple times in the query. You need to exclude example_video from the query
Hello folks Im new to Django(I have just the finished the tutorial) but I think i understand the basic concepts of it .Im writing here because Im trying to do something "difficult" for my current experience with django and searching the internet didnt give me a solution .What im trying to do is to create a dynamic model based on the number of entries of another model .To be more exact lets say i got the following model :
class criteria(models.Model):
criteria_text = models.CharField(max_length=200)
monotonicity = models.CharField(max_length=1,choices=(('+','ASCEDING'),('-','DESCENDING')),default='+',verbose_name='Monotonicity')
worst = models.IntegerField(default=0)
best = models.IntegerField(default=0)
What i want to do is create all the criteria models instances i want through the django admin panel and then query for all the creteria_text instances in the database and make a model with an attribute for every criteria_text instance.
So lets say I add the following criteria to the database(these are criteria_text attributes of criteria objects: Color,Weight,Price .
I want to end up with a model like this :
class Alternative(models.Model):
Color = models.IntegerField(default=0)
Weight = models.IntegerField(default=0)
Price = models.IntegerField(default=0)
The thing is that in my application this one has to happen a lot of times so i cannot make model each time someone adds an Alternative based on different criteria .
After searching i found that i can define dynamic models using the following format :
attrs = {
'name': models.CharField(max_length=32),
'__module__': 'myapp.models'
}
Animal = type("Animal", (models.Model,), attrs)
So the question is how can I define "attrs" based on a query that gets all the criteria in the database ?Can i define a relationship of this dynamic model with another model ? Also the models already created should be updated if a user adds more criteria .
Is something like this possible ?
If so please show me the path .
I don't think defining dynamic models is a good solution here (or anywhere, really). Rather, you need a relationship that can have as many items as there are criteria instances.
It might be something like this:
class Alternative(models.Model):
name = models.CharField(...)
choices = models.ManyToManyField("Criteria", through="AlternativeChoice")
class AlternativeChoice(models.Model):
alternative = models.ForeignKey('Alternative')
criteria = models.ForeignKey('Criteria')
value = models.IntegerField(default=0)
The real logic will belong in the form, where you will need to create options for each criteria entry, and validate the AlternativeChoice dependent on the related criteria.
I have a site that pulls feeds in from various sites. Most of these are via RSS, but a few are via API, like HackerNews. I have a ListView that shows all of my feeds, so I want to keep all of these the same type of model.
What I'm looking to do is this (does not work):
class Feed(models.Model):
name = models.CharField(max_length=75)
rss = models.URLField(blank=True, null=True)
def get_feed_data(self):
# return data based on self.rss
class HackerNewsFeed(Feed):
name = "Hacker News" # Doesn't work
def get_feed_data(self):
# Return data based on Hacker News API
The answers to this question seem to say that I should simply use the Feed model with custom methods based on the name...then I would manually input "HackerNews" into the database and this would automatically trigger my API code. It feels a little hacky.
What is the best way to achieve what I'm looking for?
Since Feed is a models.Model you can only assign model fields as class parameters. Assigning name = "Hacker News" won't work on models. Since it doesn't look like the shape of the data needs to change depending on the feed type, then just leave your model as-is, and implement your feed fetching based on the self.name attribute. Something like this:
# assumes a file called `feedfetcher.py` in the same
# directory as your `models.py` file
from . import feedfetcher
class Feed(models.Model):
name = models.CharField(max_length=75)
rss = models.URLField(blank=True, null=True)
def get_feed_data(self):
return feedfetcher.fetch(self.name)
# feedfetcher.py
def fetch(name):
if name == 'Hacker News':
# get hacker news feed
elif name == 'Reddit':
# get reddit feed
else:
# we have no fetcher for this
# kind of feed yet.
raise ValueError('No fetcher for {}'.format(name))
If you add too many feeds this will quickly become unruly. I would probably split RSS feeds into a common method or class to make handling of those automatic. Add the following attribute to your model:
feed_type = models.CharField(choices=(('RSS', 'RSS'), ('API', 'API'))
And then you could check what the feed type is within get_feed_data and if it's RSS, hand off to a specific RSS feed handler. I'm assuming each API will be different though, so you can keep the fetch method above to figure out and call each individual API.
I suggest inserting the fixed Feeds using fixtures and then make get_feed_data conditional based on name.
def get_feed_data(self):
if self.name == "Hacker News":
# Return data based on Hacker News API
else:
# return data based on self.rss
Here are my models and the manager class. I think the problem is in the PostingFilterManager below. They way I search of the keywords in title and body_text is wrong.
I want to query for a list of keywords in title and body_text of Postings model below. I am not getting any error but at the same time nothing is displayed on browser. I am sure that the filter should return a posting.
class PostingFilterManager(models.Manager):
def get_by_keywords(self,wordlist):
print "called"
posts=super(PostingFilterManager,self).get_query_set().filter
(Q(body_text__in=wordlist) | Q(title__in=wordlist))
print posts
return posts
class Postings(models.Model):
carinfo=models.ForeignKey('CarInfo')
title = models.CharField(max_length=100, blank=True)
body_text = models.TextField(blank=True)
objects=models.Manager()
filters=PostingFilterManager()
def __unicode__(self):
return unicode(self.website)
my view:
def detail(request,year):
result=Postings.filters.get_by_keywords(['hello'.'world','clean'])
return HttpResponse(result)
This won't work because of how you constructed query. Let's analyze your query:
filter(Q(body_text__in=wordlist) | Q(title__in=wordlist))
It seems you want to search for keywords in content and titles. But body_text__in=wordlist means that filter will be satisfied if your whole body of text will be either 'hello' or 'world' or 'clean.' My assumption is that it's not what you want. Instead what you are looking for is iterating over keywords and using __contains condition. I haven't written Django queries in quite a while, so I will write some ugly code that maybe will present the general idea:
full_query = null
for keyword in wordlist:
if full_query is null:
full_quey = Q(body_text__contains=keyword) | Q(title__in=keywords)
else:
full_query = full_query | (Q(body_text__contains=keyword) | Q(title__in=keywords))
posts=super(PostingFilterManager,self).get_query_set().filter
(Q(body_text__in=wordlist) | Q(title__in=wordlist))
Also, additional suggestion. What you are doing here is full text search and what you are doing is probably not the best way of doing it. Probably a better way would be to construct an index and search an index.
Consider reading Wikipedia article about full text search, especially indexing: http://en.wikipedia.org/wiki/Full_text_search
I have 3 models.
class Picture(models.Model)
name = models.CharField(max_length=255)
image_field = models.ImageField(upload_to="foo/")
slug = models.SlugField()
[...]
class Size(models.Model):
name = models.CharField(max_length=255)
width = models.IntegerField()
height = models.IntegerField()
crop = models.BooleanField(default=True)
upscale = models.BooleanField(default=False)
def __unicode__(self):
return self.name
class Cache(models.Model):
size = models.ForeignKey('Size')
picture = models.ForeignKey('Picture')
image_field = models.ImageField(upload_to="picture/resize/")
I want to use them as follows: First generate Picture objects. Then create Size objects. For every Size and Picture a Cache object should be generated when needed.
My problem is that I don't know where to put the code. It should be something like (pseudocode):
def get_cached_picture(Picture,Size):
try:
cacheObj = Cache.objects.get(picture=Picture, size=Size):
[.. use cacheObj ..]
except Cache.DoesNotExist:
[.. resize Picture according to Size, insert into cache, use it ..]
So where can I plug this code ? I know I could do this within a view, but is there a way to embed it into the models ? Cache should never be filled in the admin, instead it should be generated whenever a certain combination between Cache and Picture is needed.
It is probably easy to do, but I'm lacking of the right keyword for google.
Assumptions:
You want to be able to load a "Representation" of an image at a certain size on the fly.
Size model will store a predefined set of sizes that a Representation can have.
I am going to refer to your Cache model as Representation because I think it makes more sense in context here.
The entry-point of this process would obviously be a view. A request comes in and you determine you need to search "Image1.jpg" # 800x600. The simplest approach is just to put your queries right into the view. But for reusability, it might be better to do any of the following:
A utility function which is then called from the view to retrieve a Representation object
A classmethod of your Representation model, since you are already referencing Picture and Size as foreign keys.
Using a custom manager on the Representation model to do something similar to the above
Any of these will make it reusable as an app if someone else were to have their own views and needed to simply retrieve a Rep instance directly.
While your pseudocode refers to this process being on the Picture mode, I maintain that it should probably be on the Representation model, since it contains both foreign keys and you can easily see if you have a proper rep. If not, create it.
The view should only have to call something simple as opposed to having all of the logic:
# as classmethod
rep = Representation.get_cached_picture(picture, size)
# or with a manager
rep = Representation.objects.get_cached_picture(picture, size)