Joining two tables django newbie qustion - django

mysqllite table joining in django is new to me. I can query just fine on one table. and somewhat at joining via just raw mysql. What i need is an example of how to code to tables together Ie below the models and the first qustion on my project is to find all the teams that are in Atlantic confrence
I have
this in view
"atlanticsoccer": League.objects.filter(name__contains="atlantic")
this in html
<h5>Question 1</h5>
{% for whatever in atlanticsoccer %}
<li>{{whatever.name}}</li>
<li></li>
{% endfor %}
</ol>
which gives me all my Atlantic conference leauges. But i can't seem to find an example of how to join the teams by id . I have linked below the models view If i can get an example of how to do the first I can figure out the html. Thanks in advance for helping a new coder.
Models.py
from django.db import models
class League(models.Model):
name = models.CharField(max_length=50)
sport = models.CharField(max_length=15)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Team(models.Model):
location = models.CharField(max_length=50)
team_name = models.CharField(max_length=50)
league = models.ForeignKey(League, related_name="teams")
class Player(models.Model):
first_name = models.CharField(max_length=15)
last_name = models.CharField(max_length=15)
curr_team = models.ForeignKey(Team, related_name="curr_players")
all_teams = models.ManyToManyField(Team, related_name="all_players")
views.py
from django.shortcuts import render, redirect
from .models import League, Team, Player
from . import team_maker
def index(request):
context = {
"leagues": League.objects.all(),
"teams": Team.objects.all(),
"players": Player.objects.all(),
"atlanticsoccer": League.objects.filter(name__contains="atlantic")
}
return render(request, "leagues/index.html", context)
def make_data(request):
team_maker.gen_leagues(10)
team_maker.gen_teams(50)
team_maker.gen_players(200)
return redirect("index")
index.html
<h5>Question 1</h5>
{% for whatever in atlanticsoccer %}
<li>{{whatever.name}}</li>
<li></li>
{% endfor %}
</ol>

First get all teams that have a league with a name of "atlantic":
atlanticsoccer = Team.objects.filter(league__name__contains='atlantic')
Then iterate through them in your template and print whatever you want:
<ul>
{% for team in atlanticsoccer %}
<li>{{team.location}}</li>
<li>{{team.team_name}}</li>
<li>{{team.league.name}}</li>
<li>{{team.league.sport}}</li>
{% endfor %}
</ul>

Related

Get image.url as atributte in a related model in django template

I have a ListView where a I want to list products. The problem is that I can't get the related image of these products as they are in a different model.
The model for products is:
class Product(models.Model):
brand = models.ForeignKey(Brand, on_delete=models.CASCADE, verbose_name='marca')
name = models.CharField('nombre', max_length=40)
description = models.TextField('descripción', blank=True)
price = models.DecimalField(max_digits=8, decimal_places=2)
slug = models.SlugField(max_length=50)
active = models.BooleanField('activo',default=True)
in_stock = models.BooleanField('en stock', default=True)
tags = models.ManyToManyField(ProductTag, blank=True)
date_updated = models.DateTimeField('última actualización', auto_now=True)
The model of images is:
class ProductImage(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE, verbose_name='producto')
image = models.ImageField('imagen', upload_to="product-images")
thumbnail = models.ImageField('miniatura', upload_to="product-thumbnails", null=True)
To get both models in the template I used context.update in the view.
class ProductListView(ListView):
template_name = 'product_list.html'
context_object_name = 'products_list'
model = models.Product
paginate_by = 4
def get_context_data(self, **kwargs):
context = super(ProductListView, self).get_context_data(**kwargs)
context.update({'product_images_list': models.ProductImage.objects.all()})
return context
def get_queryset(self):
tag = self.kwargs['tag']
self.tag = None
if tag != 'all':
self.tag = get_object_or_404(models.ProductTag, slug=tag)
if self.tag:
products = models.Product.objects.active().filter(tags=self.tag)
else:
products = models.Product.objects.active()
return products.order_by('name')
Additionally, I created a filter to iterate both models in a forloop but I think is useless as I don't want to iterate both models, I just want to get the first image that matches the product's FK to show it in the template:
from django import template
register = template.Library()
#register.filter(name='zip')
def zip_lists(a, b):
return zip(a, b)
The template I'm using is:
{% extends 'base.html' %}
{% load humanize %}
{% load product_extras %}
{% block content %}
<div class="destacados">
{% for product, image in products_list|zip:product_images_list %}
<div class="collections coll-watches">
<img class="foto" src="{{ image.thumbnail.url }}">
<p class="prod-description">{{ product.name }}</p>
<p class="prod-description prices"><strong>$ {{ product.price|intcomma }}</strong></p>
<a class="boton-tr boton-tr-watches" href="#">Agregar al carrito</a>
</div>
{% endfor %}
</div>
{% endblock content %}
As you can see the problem is in <img class="foto" src="{{ image.thumbnail.url }}">. I know this is incorrect, but I don't know how to get the image related to the product through its FK.
I'm new i django (only two months) and I'm sure this should be easier, but I can figure it out...
Any help would be appreciated!!
Best regards
you can define a get image url method in your product model as below
def get_image_url(self):
img = self.productimage_set.first()
if img:
return img.thumbnail.url
return img #None
and call it in your templates get_image_url
Thank you very much #bmons. I had to modify the method a little bit, but your answer gave me the clue I needed.
This is the final code:
def get_image_url(self):
img = self.productimage_set.first().thumbnail.url
if img:
return img
return img #None
When Using img = self.productimage_set.thumbnail.first() I get a RelatedManager error.
Anyway, I really appreciate your help!! Cheers

Compare user attributes in template using IF statement

I have a list of users and want to display their tasks only if the selected user belongs to the same department. My Models have a department field that I want to compare.
This is my template code.
{% extends 'view_users.html' %}
{% block view_user_tasks %}
Back
<p> todo lists for {{ user }}</p>
{% for todo in view_user_tasks %}
<a id="{{todo.id}}" class="todo_remove"></a>
{% endfor %}
{% endblock view_user_tasks %}
What i want to do is evaluate this condition:
if request.user.Department == user.Department:
show user tasks
This are my respective views.
class ViewUsers(ListView):
model = CustomUser
template_name = 'view_users.html'
class ViewUserTasks(ListView):
model = Todo
template_name = 'view_user_tasks.html'
context_object_name = 'view_user_tasks'
My models.py
class Todo(models.Model):
title = models.CharField(max_length=30)
body = models.CharField(max_length=255)
created_at = models.DateTimeField(auto_now_add=True, blank=True)
checked = models.BooleanField(default=False)
owner = models.ManyToManyField(CustomUser)
id = HashidAutoField(primary_key=True)
def __str__(self):
return "%s: %s" % (self.title, self.body)
class CustomUser(AbstractUser):
Department = models.CharField(max_length=30, blank=True)
How can I be able to accomplish this?
Do your filtering logic in the view. You can override the default get_queryset method and return only the Todos that you want.
class ViewUserTasks(ListView):
template_name = 'view_user_tasks.html'
context_object_name = 'view_user_tasks'
def get_queryset(self):
return Todo.objects.filter(user__Department=self.request.user.Department)
And then just loop through the returned data like you are already doing.
If I clearly understand your question, you can compare it like this:
{% if todo.user.id == user.id %}

How to retrieve data from one to many relations in django?

I am making my personal website using django 1.10
Here is models of skill app:
from __future__ import unicode_literals
from django.db import models
# Create your models here.
class Skill(models.Model):
name = models.CharField(max_length=256)
created_at = models.DateTimeField(auto_now=False, auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True, auto_now_add=False)
def __unicode__(self):
return self.name
def __str__(self):
return self.name
class Subskill(models.Model):
skill = models.ForeignKey(Skill, on_delete=models.CASCADE)
name = models.CharField(max_length=256)
link = models.CharField(max_length=256)
created_at = models.DateTimeField(auto_now=False, auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True, auto_now_add=False)
def __unicode__(self):
return self.name
def __str__(self):
return self.name
And view:
from django.shortcuts import render
from skill.models import Skill,Subskill
# Create your views here.
def home(request):
skill = Skill.objects.all()
subskill =Subskill.objects.all()
context = {'skills':skill,
'subskills':subskill}
return render(request, 'skill.html', context)
This is my template page:
skill.html
{% block skill %}
{% for subskill in subskills %}
{{subskill.skill.name}}
{{subskill.name}}
{% endfor %}
{% endblock skill %}
Let assume, there is a skill named web design which has two subskill named html and css.
I want to render in view page as like as skill name and it's two child name:
Web design
Html
CSS
But it renders as like Web design Html Web design CSS
Please help me about this issue.
You can do realted query on skill itself
https://docs.djangoproject.com/en/1.10/topics/db/queries/#backwards-related-objects
# example
skill_obj = Skill.objects.all()[0]
subskills = skill_obj.subskill_set.all()
Or in your case
def home(request):
skills = Skill.objects.all().prefetch_related('subskill_set') # optimizing
context = {'skills':skills}
return render(request, 'skill.html', context)
In template
{% for skill in skills %}
{{skill.name}}
{% for subskill in skill.subskill_set.all %}
{{subskill.name}}
{% endfor %}
{% endfor %}

Error 'NoneType' object has no attribute '_default_manager' when I create a view of Model instance

I'm new in Django and I'm developing an app but I'm stuck in this Error.
First I want to apologize for my English since is not my first language and then I hope I'm in the right place to ask for little help.
I'm developing a website about Publication of articles. The page "Publication" return a list of the model instances - in my case all the publications in the db.
What I'm trying to do is to assign a url to each of the instances of my Model, such that the user can click on it and see the page which is populated with other relevant information of that instance.
To do this I'm using get_absolute_url in my template and DetailView in my view.
The list of all the instance works fine but when I click on each of the instance I run the error 'NoneType' object has no attribute '_default_manager' .
I google already and try to follow some guidelines here and there, and try to find solution in Django doc couldnt figure out the solution...
Here my code:
models.py
class Publications(MPTTModel):
code = models.CharField(max_length=50)
title = models.CharField(max_length=150)
date = models.DateField(null=True)
magazine = models.CharField(max_length=50)
country = models.CharField(max_length=30)
slug = models.SlugField(max_length=150)
img01 = models.ImageField(upload_to="photo", blank=True, null=True)
link = models.URLField(max_length=200, blank=True, null=True)
template = models.ForeignKey("Template", related_name="publications", null=True, blank=True)
parent = models.ForeignKey('self', null=True, blank=True, related_name='children')
control_field = models.CharField(max_length=15)
class Meta:
verbose_name_plural = "Publications"
def __unicode__(self):
return self.title
def get_absolute_url(self):
return reverse('mag-publication',args=(self.slug,))
publications.html
{% load mptt_tags %}
{% load sito_tags %}
{% full_tree_for_model myApp.Publications as publications %}
{% for publications,structure in publications|tree_info %}
{% if publications.img01 %}
<div id="title_publication_container">
{{ publications.magazine }}
</div>
{% else %}
....
{% endif %}
{% endfor %}
urls.py
urlpatterns = patterns('',
url(r'^(?P<id_page>\d+)/(?P<slug>[\w-]+)/$', pages,),
url(r'^(?P<id_page>\d+)/(?P<slug_page>[\w-]+)/(?P<id>\d+)/(?P<slug>[\w-]+)/$', projects,),
url(r'^mag-publication/(?P<slug>[\w-]+)/$', PublicationDetailView.as_view() , name='mag-publication'),
)
view.py
class PublicationView(object):
queryset = Publications.objects.all()
class PublicationListView(PublicationView, ListView):
paginate_by = 20
class PublicationDetailView(PublicationView, DetailView):
slug_field = 'slug'
The error show me this Debug informations:
AttributeError at /6/publications/*title_publication*/
**'NoneType' object has no attribute '_default_manager'**
Request Method: GET
Request URL: .../6/publications/*title_publication*/
Django Version: 1.5.4
Exception Type: AttributeError
Exception Value: 'NoneType' object has no attribute '_default_manager'
Exception Location: /home/gabriele/virtual_envs/virt2/lib/python2.7/site-packages/feincms/views/cbv/views.py in get_object, line 20
Python Executable: /home/gabriele/virtual_envs/virt2/bin/python
Maybe the problem has something to do with feincms as it said in the "Exception Location" but everything came out after I tried to work on the instance of the Model.
Thank you for your help.
You probably didn't add feincms.module.page to your INSTALLED_APPS as per the documentation. If you follow the traceback, the error appears in get_object() where it tries to access the page model.
Are you using an older FeinCMS version? Newer versions raise a warning in that case.
Well i don't know for feincms but in your views you have :
class PublicationView(object):
queryset = Publications.objects.all()
class PublicationListView(PublicationView, ListView):
paginate_by = 20
class PublicationDetailView(PublicationView, DetailView):
slug_field = 'slug'
First of all you don't need to set the slug field if his name is already 'slug'.
And an other thing :
You inherit from PublicationView in your PublicationDetailView, but the DetailView need a single object, just try like this in your url file :
url(r'^mag-publication/(?P<slug>[\w-]+)/$', DetailView.as_view(model=Publications) , name='mag-publication')
Off course don't forget to import DetailView and Publications model into your url file.
EDIT 20/08/2014
In your get_absolute_url method you use :
return reverse('mag-publication',args=({'slug':self.slug}))
If you want to use dict for params you must use :
return reverse('mag-publication',kwargs={'slug':self.slug})
And if you want to use args you must do :
return reverse('mag-publication',args=(self.slug,))
I solved part of the problem. I used a combination of get_absolute_url and DetailView.
I can see the perfectly the list of the publications in publication.html but when I click to one of them the app show me - in publications_detail.html - the detail of all the instances of the Model instead only one.
From publications in admin "view on site" it works but there's the same problem, show me all the instances together.
The question is how to catch only one instance. Follow the code :
models.py
class Publications(MPTTModel):
title = models.CharField(max_length=150)
slug = models.SlugField(max_length=150)
img01 = models.ImageField(upload_to="photo", blank=True, null=True)
template = models.ForeignKey("Template", related_name="publications", null=True, blank=True)
parent = models.ForeignKey('self', null=True, blank=True, related_name='children')
control_field = models.CharField(max_length=15)
class Meta:
verbose_name_plural = "Publications"
def __unicode__(self):
return self.title
def get_absolute_url(self):
return reverse('mag-publication',args=(self.slug,))
views.py
class PublicationsDetail(DetailView):
queryset = Publications.objects.all()
template_name = 'website/publications_detail.html'
urls.py
url(r'^mag-publication/(?P<slug>[\w-]+)/$', PublicationsDetail.as_view()
publications_detail.html
{% load mptt_tags %}
{% load sito_tags %}
{% full_tree_for_model napeApp.Publications as publications %}
{% for publications,structure in publications|tree_info %}
{% if publications.img01 %}
<div id="title_publication_container">
{{ publications.magazine }}
</div>
{% else %}
....
{% endif %}
{% endfor %}
In my case I just renamed meta to Meta and it solved.maybe it is related to sensitive capital class name

Django output html time is 8 hours ahead of database time

I'm very new to Django and I've been learning the framework from the book "Practical django Projects" (the book teaches us to write a cms). My code runs fine, but I have time problem with the get_absolute_url function below. It's actually outputting the link 8 hours ahead of the time saved in my database. I used python shell to look at the saved time in the database and the time saved in the admin interface, they are all correct. But when I use the get_absolute_url func below to generate the link in browser, it becomes 8 hours ahead and throws the day off. I set the correct zone in my Django setting file. I cannot figure out what's wrong.
How I can fix this (I'm using sqlite3 for my database, Django 1.4.1)?
Here is my code for the Entry class:
import datetime
from django.db import models
from django.contrib.auth.models import User
from tagging.fields import TagField
from markdown import markdown
from django.conf import settings
from django.utils.encoding import smart_str
class Entry(models.Model):
live = LiveEntryManager()
objects = models.Manager()
#define constant options
LIVE_STATUS = 1
DRAFT_STATUS = 2
HIDDEN_STATUS = 3
STATUS_CHOICES = (
(LIVE_STATUS, 'Live'),
(DRAFT_STATUS,'Draft'),
(HIDDEN_STATUS, 'Hidden'),
)
#adding features to admin interface
class Meta:
ordering = ['-pub_date']
verbose_name_plural = "Entries"
#define model fields:
title = models.CharField(max_length=250)
excerpt = models.TextField(blank=True) #It's ok to not add anything for this field
body = models.TextField()
pub_date = models.DateTimeField(default=datetime.datetime.now())
slug = models.SlugField(unique_for_date='pub_date')
enable_comments = models.BooleanField(default=True)
featured = models.BooleanField(default=False)
status = models.IntegerField(choices=STATUS_CHOICES, default=LIVE_STATUS)
#HTML
excerpt_html = models.TextField(editable=False, blank=True)
body_html = models.TextField(editable=False, blank=True)
#third party:
tag = TagField()
#relationship fields:
categories = models.ManyToManyField(Category)
author = models.ForeignKey(User)
#define methods:
def save(self, force_insert=False, force_update=False):#modify the model.save() method
self.body_html = markdown(self.body)
if self.excerpt:
self.excerpt_html = markdown(self.excerpt)#from excerpt field to excerpt_html
super(Entry, self).save(force_insert, force_update)
def get_absolute_url(self):
return "%s" % self.pub_date.strftime("year:%Y/day:%d/hour:%H/minute:%M/second:%S")
##models.permalink
#def get_absolute_url(self):
#return ('coltrane_entry_detail', (), {'year': self.pub_date.strftime("%Y"),
'month': self.pub_date.strftime("%b").lower(),
'day': self.pub_date.strftime("%d"),
'slug': self.slug})
def __unicode__(self):
return self.title
This is my entry_archive.html:
{% extends "base_entries.html"%}
{%block title%}{{block.super}} | Latest entries{% endblock %}
{% block content %}
{% for entry in latest %}
<h2>{{entry.title}}</h2>
<p>Published on {{ entry.pub_date|date:"F j P s, Y" }}</p>
{% if entry.excerpt_html%}
{{entry.excerpt_html|safe}}
{% else %}
{{entry.body_html|truncatewords_html:"50"|safe}}
{% endif%}
<p>Read full entry ...</p>
{% endfor %}
{%endblock%}
{%block whatis%}
<p>This is a list of the latest {{latest.count}} entries published in my blog.</p>
{% endblock %}
I couldn't post screenshot because i'm a new user. {{ entry.pub_date|date:"F j P s, Y" }} in my html give me correct time: December 28 11:24 a.m. 45, 2012. But {{entry.get_absolute_url}} gives me year:2012/day:28/hour:19/minute:24/seconds:45
I add the () to pub_date = models.DateTimeField(default=datetime.datetime.now()) as you guys suggested, but the result is still the same(the book actually suggests not to add () ). The thing troubles me is that {{ entry.pub_date|date:"F j P s, Y" }} gives me the correct time on my html, but {{entry.get_absolute_url}} is 8 hours ahead. I set my setting.py time zone to TIME_ZONE = 'America/Los_Angeles'. Thanks for all the quick response, but this is killing me...
change the following:
pub_date = models.DateTimeField(default=datetime.datetime.now)
to Either
pub_date = models.DateTimeField(default=datetime.datetime.now())
or
pub_date = models.DateTimeField(auto_now_add=True)