I'm new to django, and i want to show field that related to foreign key in another table. this is the table.
i want to career table got the career_tag_name and hex_code from table color.
i've tried the Career.objects.raw()
this is the query in views.py:
careers = Career.objects.raw('''SELECT website_career_tag.career_tag_name,website_color.hex_code, website_career.*
from website_career INNER JOIN website_career_tag on website_career_tag.id = website_career.career_tag_id_id
LEFT JOIN website_color on website_career_tag.color_id_id = website_color.ID''')
it works perfectly, until i want to use filter() by career_tag_name. when i use query set it's more easy than make it raw to filter.
how do i make those raw query to query set?
It's always better to use django's own ORM rather than raw query and it's quite easy as well. Django querysets always stores all related table informations everywhere, you should just reference to them from the object. For example for career list view you can get all career informations and select the related fields to make loops less expensive in templates:
careers = Career.objects.select_related('career_tag_id', 'career_tag_id__color_id')
And then in a template just refer to related objects as:
{% for career in careers %}
{{ career.career_tag_id.career_tag_name }}
{{ career.career_tag_id.color_id.color_name }}
{% endfor %}
Related
I want to create a for loop in dbt that loops through two columns of a table in my database and created case when statements using the values in each row of the two columns. Just like this:
{% set locations = {'%United-States%':'United States', '%USA%':'United States'} %}
select
case
{% for feeder, correct in locations.items() %}
when lower(locationname) like {{feeder}} then {{correct}}
{% endfor %}
end as city
from table
I was able to create lists for both feeder and correct, but I am not able to merge them as key-value pairs of a dictionary to loop through it. Any ideas on how should I do this?
Sounds like you have two problems:
fetch data from another table, and
use that data to populate a case when statement.
Big thing to remember is that the main thing that dbt-jinja does is create a string of SQL. That said, there is clever functionality that lets you query a database before jinja starts to put the string together.
The idea being:
fetch the values from the database that you want to have included in your SELECT query
populate the previously fetched values into the query while rendering the statement
there's two macros that may be of use in the first step:
run_query() (docs), and
dbt-utils' get_query_results_as_dict() (docs)
Something like this might work (provided you already have dbt-utils installed:
{% set locations_query %}
select feeder, correct from my_other_table
{% endset %}
{% set locations = run_query(locations_query) %}
select
case
-- not sure how this part will work yet....
{% for feeder, correct in locations.items() %}
when lower(locationname) like {{feeder}} then {{correct}}
{% endfor %}
end as city
from table
In my Django project I have a model called Item, which basically stores a lot of items. I also make use of Django's built in User model to allow user's to register and login. What I now want is for each user to be able to check an item as "collected".
I'm not feeling comfortable in the way I've solved it right now, that's why I'm asking if this is good practice for this problem? Or is there any best practice to solve my problem?
This is my solution now:
from django.contrib.auth.models import User
class Item(models.Model):
...
users_collected = models.ManyToManyField(User, related_name='items_collected')
And I use this as: If there is a record between a user and an item, then the item is considered as collected by that user. To mark an item as collected I simply add a record, and to again mark it as not collected, I remove that record.
In my detail template for a specific item category I have the following code to display if a user has an item collected, or not.
{% for item in items %}
{{ item.name }} -
{% if user in item.users_collected.all %}
in collection.
{% else %}
not in collection.
{% endif %}
My main concern using this method to solve the problem is the number of created and removed records for the ManyToMany-table that is created, as users will check and uncheck items regularly. I don't really like to put a new field to the Item's model either, as I guess it makes it less re-usable?
Yes, I think this represents good practice. You need to persistently store the relationship between Users and Items, and your method does so in the most straightforward way possible.
A high database write rate can certainly be problematic, but how else would you store this information? One can imagine more exotic implementations, where, for example, each User has a bit-array field with one bit per Item indicating whether it is collected or not. But unless you have a good reason for doing something like that I would start with this straightforward approach.
One bit of advice I have is to make the M2M through table (see the documentation) explicit. That will promote clarity, and make it easy to add any extra fields as the relationship becomes more complex.
I can fetch the data like this.
value= mymodel.objects.get(anycondition)
OR
value= mymodel.objects.filter(anycondition)
and can send them to my template with context.
But if I want to select all the data from a table(for all users not only one) as this query does
value= mymodel.objects.all()
and send this value to my template and can see there field by field
e.g.
my table has two fields name and phone no and I use the above query( value= mymodel.objects.all()) now if i want to see all names then i can see that and if i want to see phone no. I can see that too.
I have tried this and it doesn't work and I even I do not know it is possible or not.
If it is possible then please let me know how I can do this ?
I hope you understand my question. !!
Thanks in advance
.all() will return a list of objects that represent the rows in your model. .get() only returns one object. Your template is trying to print the result of all() if it was one object.
This is the same as if you had a list and you wanted to loop through it. In your view you would do:
product = Product_attributes.objects.all()
for i in product:
print i.size
print i.color
The equvalent for the template is:
<ul>
{% for i in product %}
<li>{{ i.size }}</li>
<li>{{ i.color }}</li>
{% endfor %}
</ul>
Although this question isn't clear it seems like you are having a bit of problem with Field Lookups. It is fairly easy to learn Here is a link to get you started
class Comment (models.Model):
user = models.ForeignKey(User, related_name="comments")
title = models.TextField(max_length=256)
comment = models.TextField(max_length=1286)
created = models.DateTimeField(db_index=True)
Now how do I get latest comments but limit the results to only (say 3) comments per same user?
Here is how its done in pure SQL: How to select a limited amount of rows for each foreign key?
I guess, this would work:
Comment.objects.filter(*[
~Q(id__in=user.comments.order_by('-created')[3:].values_list('id', flat=True))
for user in User.objects.all()
])
However, it seems like neither pythonic nor efficient way to solve the problem. (Efficiency problem could be somewhat solved by using cache, but still.)
What are you trying to achieve, anyway? You could just fetch all user's comments and use only the latest three. Assuming that your comments are ordered by -created field:
{% for user in users %}
{% for comment in user.comments.all|slice:"3" %}{{ comment }}{% endfor %}
{% endfor %}
Slicing will be converted to LIMIT clause in SQL query, so you won't be getting all the comments anyway. Of course, there would be more that one query executed to get all the comments, so using template caching can help.
Again, this may not make sense in your case. If it doesn't, it would be better if you clarify the requirements.
Raw SQL
If you know how to do what you want with raw SQL ([1] may help), then you need to just find a way to put it into extra() somehow ([2] is an example of complex extra query which may give you an idea).
[1] How to select a limited amount of rows for each foreign key?
[2] django's .extra(where= clauses are clobbered by table-renaming .filter(foo__in=... subselects
Thanks to some fantastic help on a previous question I have managed to put together my query. Everything works swimmingly save one issue.
careers = Career.objects.filter(job__dwarf__user = 1).annotate(dwarves_in_career = Count('job__dwarf'))
In my view this does exactly what I want and when I loop it in my template like so:
{% for career in careers reversed %}
<li>{{ career.name }}: {{ career.dwarves_in_career }}</li>
{% endfor %}
I get what I expected. My issue is that the above code will only return the Careers that have dwarves. I need it to return all careers:
Unassigned: 1
Construction: 1
Crafting: 2
Gathering: 0
Farming: 0
is my expected results. Instead the last two rows are not there because I am filtering for the specific user. I know why it's happening, what I am trying to figure out is how to get the query to return all careers, even if their dwarf count for a particular user is 0.
I think you need to swap over your annotate and filter clauses. See the documentation on this - the way you have it, it filters the queryset, but you actually want to keep the entire queryset but just filter the annotations.
So, I eventually figured it out...
from django.db.models import Count, Q
def fortress(request):
careers = Career.objects.filter(Q(job__dwarf__user = 1) | Q(job__dwarf__user__isnull = True)).annotate(dwarves_in_career = Count('job__dwarf'))
return render_to_response('ragna_base/fortress.html', {'careers': careers})
Not exactly sure what Q is but it works!
More information here: http://www.djangoproject.com/documentation/models/or_lookups/
Basically what I am doing is finding all careers with dwarves (based on user_id) OR all careers that have no dwarves (based on null)