user
user

Reputation: 695

Django Filtering data from different model

I have two models User, Details and Skills. In Skills table can store "n" number of skills for particular user. At the time of filtering it display unique user details but keyskills not displayed. I use one to one field in Skills models but multiple user is not accepted so I use foriegn key for that.For example..

User Table

id | name
---|-----
1  | abc


Details table

id | user_id | city
---|---------|-----
1  |   1     | NY


Skills Table

id | user_id | skill
---|---------|-----
1  |   1     | C
2  |   1     | c++
3  |   1     | java

I want to filter based on skill or city. If it match any one should display whole details. I add models and views Please share you ideas

Models

class User(models.Model):
    name = models.CharField(max_length=100)


class Details(models.Model):
    user = models.OneToOneField(User)
    city = models.CharField(max_length=100, blank=True, null=True)

class Skills(models.Model):
    user = models.ForeignKey(User)
    skill = models.CharField(max_length=100, blank=True, null=True)

views

search = request.GET['keywords']
searchlist = search.split(",")
list_result= []

for search in searchlist:
    for res in User.objects.filter(Q(Skills__skill__icontains=search) | Q(Details__city__icontains=search)):
        if not res in list_result:
            list_result.append(res)
users = list_result

return render_to_response('Result.html',{'details':users},context_instance=RequestContext(request))

templates

{% for d in details %}
{{ d.name }}
{{ d.Skills.skill }}
{{ d.Details.city }}
{% endfor %}

By giving above code its works everything fine except Skills not get displayed.

Upvotes: 1

Views: 147

Answers (1)

Henrik Andersson
Henrik Andersson

Reputation: 47172

The Skills model is a ForeignKey field which means you have to access it via its _set property.

In your case it's skills_set. So your correct template syntax would be

{% for user in details %}
    name: {{ user.name }}<br/>
    {% for skill in user.skills_set.all %}
    skill: {{ skill.skill }}<br/>
    {% endfor %}
   city: {{ user.details.city }}
{% endfor %}

This differs from your OneToOneField for Details model.

Further more, your QuerySet is faulty. You shouldn't try and Q on models but the actual fields. So your current queryset should be like this:

User.objects.filter(Q(skills__skill__icontains=search) | Q(details__city__icontains=search))

Apart from that, you should really not label your things as what they really are. You've named users to details which is really confusing as you're traversing the Users object. Also you could switch out your entire view code to this

users = User.objects.filter(Q(skills__skill__icontains=search) | Q(details__city__icontains=search))

it will have the same effect.

Upvotes: 1

Related Questions