Equivalent between `MySQL JOIN` and Django - mysql

I'm using Django 1.11 and I would like to get the correct syntax in order to translate my MySQL Join request to Django QuerySet Syntax.
I have 3 different models (1 Model in my Identity application and 2 Models in my Fiscal application) as following :
#Identity.Individu
class Individu(models.Model):
NumeroIdentification = models.CharField(max_length=30, null=True, verbose_name='Numero Identification physique', unique=True)
Civilite = models.CharField(max_length=12,choices=CHOIX_TITRE, verbose_name='Civilité')
NomJeuneFille = models.CharField(max_length=30, verbose_name='Nom de jeune fille', blank=True)
Nom = models.CharField(max_length=30, verbose_name='Nom de famille')
Prenom = models.CharField(max_length=30, verbose_name='Prénom(s)')
#Fiscal.Profession
class Profession (models.Model) :
Employe = models.ForeignKey(Individu, related_name='Individu', verbose_name='Individu', null=False, to_field='NumeroIdentification')
Entreprise = models.ForeignKey(Societe, related_name='Société', verbose_name='Société', null=False, to_field='NumeroIdentification')
NumeroImpot = models.CharField(max_length=30, null=True, verbose_name='Numéro Imposition', unique=True)
Profession = models.CharField(max_length=30, verbose_name='Profession')
#Fiscal.Salaire
class Salaire (models.Model) :
Employe = models.ForeignKey(Individu, related_name='Salaire_Individu', verbose_name='Salaire_Individu', null=False, to_field='NumeroIdentification')
Salaire_B_mensuel = models.IntegerField(verbose_name='Salaire Brut Mensuel')
Salaire_N_mensuel = models.IntegerField(verbose_name='Salaire Net Mensuel')
With Mysql, I have this request which works fine :
SELECT * FROM Identity_individu i
INNER JOIN Fiscal_profession p ON i.NumeroIdentification = p.Employe_id
INNER JOIN Fiscal_salaire s on i.NumeroIdentification = s.Employe_id;
I thing I have to use prefetch_related and I wrote this (first step, join between two tables) :
#login_required
def FiscalReporting(request) :
Contribuable = Individu.objects.prefetch_related("Profession").all().filter(NumeroIdentification=Profession.Employe)
context = {
"Contribuable" : Contribuable,
}
return render(request, 'Fiscal_Reporting.html', context)
And in my template :
<table style="width:120%">
<tbody>
<tr>
<th>ID</th>
<th>État</th>
<th>N° Identification</th>
<th>Civilité</th>
<th>Nom</th>
<th>Prénom</th>
<th>Date de Naissance</th>
<th>N° Fiscal</th>
<th>Salaire Annuel Net</th>
</tr>
{% for item in Contribuable %}
<tr>
<td>{{ item.id}}</td>
<td>{{ item.Etat}}</td>
<td>{{ item.NumeroIdentification}}</td>
<td>{{ item.Civilite }}</td>
<td>{{ item.Nom }}</td>
<td>{{ item.Prenom }}</td>
<td>{{ item.DateNaissance }}</td>
<td>{{ item.NumeroImpot }}</td>
<td>{{ item.Employe.Salaire_N_annuel }}</td>
</tr>
{% endfor %}
</tbody>
</table>
Any idea about my issue ? I don't find any result up to now because my array is empty :/
Then, How I can add a supplementary join in my Django QuerySet ?

You can use prefetch_related to prefetch more than one related table like this:
Contribuable = Individu.objects.prefetch_related("Individu", "Salaire_Individu")
Note that I use "Individu" related_name of Profession model as prefetch_related argument.
Now in template you can iterate over each profession and Salaire_Individu like this:
{% for item in Contribuable %}
...
<td>{{ item.Nom }}</td>
{% for profession in item.Individu.all %}
<td>{{ profession.NumeroImpot }}</td>
{% endfor %}
{% for salary in item.Salaire_Individu.all %}
<td>{{ salary.Salaire_B_mensuel }}</td>
{% endfor %}
{% endfor %}

Related

Data view in html table from django views

I am trying to display data the tables from the database in some tables in an HTML template from django views. The problem is that the words are in a list and I want each word to be in each field in the table, How can I do that?
views.py:
def index(request):
if request.method == 'POST':
tp = request.POST.get('tp')
ms = request.POST.get('mode_selection')
if tp == "Download" or tp == "Preview":
usr = User.objects.get(username=request.user)
if ms=='2':
data=WordDifferentTable.objects.filter(user=usr).values_list('word1','word2',word3', 'word4', 'word5', 'result')
hds = ['word1', 'word2', 'word3', 'word4', 'word5', 'result']
elif ms=='3':
data = LogicAnaloguiesTable.objects.filter(user=usr).values_list('word1', 'word2',
'word3', 'word4', 'word5', 'result', 'distance_to_word12')
hds = ['word1', 'word2', 'word3', 'word4', 'word5', 'result',
'distance_to_word12']
elif ms=='4':
data = SimilarWInContextTable.objects.filter(user=usr).values_list('word1',
'word2', 'word3', 'word4', 'word5', 'distance_to_word12', 'distance_to_word13',
'distance_to_word23')
hds = ['word1', 'word2', 'word3', 'word4', 'word5', 'distance_to_word12',
'distance_to_word13', 'distance_to_word23']
else:
data = WordsTable.objects.filter(user=usr).values_list('word1', 'word2', 'word3',
'word4', 'word5',)
hds = ['word1', 'word2', 'word3', 'word4', 'word5',]
return render (request, "base.html",context)
else:
return render (request, "base.html")
HTML table:
{% if data %}
<div style="padding-top: 30px" class="row">
<h3 align="center">Preview</h3>
<table style="border: 1px solid #dddddd;">
<thead>
<tr style="border: 1px solid;">
{% for h in hds %}
<th style="border: 1px solid;">{{h}}</th>
{% endfor %}
</tr>
</thead>
<tbody style="border: 1px solid;">
{% for d in data %}
<tr>
{% for word in data %}
<td style="border: 1px solid;">{{ word }}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endif %}
An example of how the data is shown, I want each word to be in each field:
When you iterate over data you get tuples, you need to iterate over each tuple to get your table cells
{% for d in data %}
<tr>
{% for word in data %}
<td style="border: 1px solid;">{{ word }}</td>
{% endfor %}
</tr>
{% endfor %}

How to get related ManyToMany objects from different model and render them in HTML format?

I tried to look up the order class and get the last 5 orders with their customer and items. But got the following exception:
*Exception Type: ValueError
Exception Value:
Negative indexing is not supported.*
Here are the models:
class Customer(models.Model):
first_name = models.CharField(max_length=255)
last_name = models.CharField(max_length=255)
class Order(models.Model):
placed_at = models.DateTimeField(auto_now_add=True)
customer = models.ForeignKey(Customer, on_delete=models.PROTECT)
class OrderItem(models.Model):
order = models.ForeignKey(Order, on_delete=models.PROTECT)
product = models.ForeignKey(Product, on_delete=models.PROTECT)
And here is the view class:
def last_5_orders(request):
orders = Order.objects.select_related('customer').prefetch_related('orderitem_set__product').order_by('placed_at')[-5:]
return render(request, 'last_5_orders.html', {'orders': orders})
And finally in last_5_orders.html file I have:
{% for order in orders %}
<h1>
{{ order.id }} : {{ order.custumer.first_name }} {{ order.custumer.last_name }} PURCHASED {{order.orderitem_set.product}}
</h1>
{% endfor %}
Any ideas about resolving this issue?

Jinja2 if statement, where MySQL date type is null

I am generating a table using the jinja2 notation, within a flask app querying data from a MySQL database.
The html template:
{% for j in JRN %}
<tr>
<td>{{ j[0] }}</td>
{% if j[1] != '0000-00-00' %}
<td>{{ j[1] }}</td>
{% else %}
<td></td>
{% endif %}
...
{% endfor %}
producing:
Where Date, j[1], is null, or ‘0000-00-00’, I would like the table to be blank, rather than ‘None’.
The Date field is of type: date
In addition to the if clause shown above, I have tried:
...
{% elif j[1] != '0' %}
<td>{{ j[1] }}</td>
{% elif j[1] != 0 %}
<td>{{ j[1] }}</td>
{% elif j[1] != 'None' %}
<td>{{ j[1] }}</td>
{% elif j[1] != 'NULL' %}
<td>{{ j[1] }}</td>
{% else %}
<td></td>
...
Thanks for your help
Why don't you try using HTML entities to keep that area blank
updated code:
{% for j in JRN %}
<tr>
<td>{{ j[0] }}</td>
{% if j[1] != '0000-00-00' %}
<td>{{ j[1] }}</td>
{% endif %}
{% if j[1] == '0000-00-00' %}
<td> </td>
{% endif %}
{% endfor %}
Let me know if the problem persists.

Can I specify the order of a SQLAlchemy foreign relationship in a Jinja2 template?

I have the following two models:
class Company(db.Model):
__tablename__ = "company"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(128), index=True, unique=True, nullable=False)
comments = db.relationship("Comment", backref="comment", lazy=True)
class Comment(db.Model):
__tablename__ = "comment"
id = db.Column(db.Integer, primary_key=True)
company_id = db.Column(db.Integer, db.ForeignKey("company.id"), nullable=False)
body = db.Column(db.Text)
created_datetime = db.Column(
db.TIMESTAMP(timezone=True), default=datetime.datetime.now
)
And the following Jinja2 template:
{% for comment in company.comments %}
<div><span>{{ comment.created_datetime }}:</span> {{comment.body}}</div>
{% endfor %}
I'd like to order the comments by created_datetime desc.
Can I do that in the Jinja2 template?
In Jinja2:
Ascending
{% for comment in company.comments|sort(attribute='created_datetime') %}
<div><span>{{ comment.created_datetime }}:</span> {{comment.body}}</div>
{% endfor %}
Descending
{% for comment in company.comments|sort(attribute='created_datetime', reverse = True) %}
<div><span>{{ comment.created_datetime }}:</span> {{comment.body}}</div>
{% endfor %}
Or do the sort in Python prior to passing company to the template:
#app.route('/')
def index():
# e.g company 10
company = Company.query.join(Company.comments).filter(Company.id == 10).order_by(Comment.created_datetime.desc()).first_or_404()
render_template('index.html', company=company)

Flask SQLAlchemy relationship makes request very slow

I am using Flask SQLAlchemy for my project and I realized my customers page is very slow because I am trying to get destination for each customers. My structure looks like this.
class Users(db.Model):
__tablename__ = "users"
id = db.Column(db.Integer, primary_key=True)
first_name = db.Column(db.String(200), nullable=False)
last_name = db.Column(db.String(30), nullable=False)
created_date = db.Column(db.DateTime,nullable=False,default=datetime.datetime.now())
email = db.Column(db.Unicode(50), nullable=False)
account = db.Column(db.Unicode(10), nullable=False)
number = db.Column(db.String(30), nullable=False)
user_type = db.Column(db.String(10), nullable=False, default='ADMIN')
created_by = db.Column(db.Unicode(10), nullable=False, default='SYSTEM')
destinations = db.relationship('Destinations', backref="customer",lazy="dynamic")
class Destinations(db.Model):
__tablename__ = 'destinations'
import datetime
id = db.Column(db.Integer, primary_key = True)
did = db.Column(db.Text, nullable=False)
gateway = db.Column(db.Text, nullable=False)
channel = db.Column(db.Text, nullable=False)
own = db.Column(db.Text, nullable=False)
number = db.Column(db.Unicode(50), nullable=True)
user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
created_by = db.Column(db.Integer,nullable=False)
created_date = db.Column(db.DateTime, default=datetime.datetime.now())
expire_date = db.Column(db.DateTime, nullable=False)
record = db.Column(db.Integer, nullable=False)
auth_did = db.Column(db.Integer, nullable=False)
auth_gw = db.Column(db.Integer, nullable=False)
In my all customers page, I list all customers which the request if fast but when I try to load all destinations for each customer, the request takes a lot of time for it to load.
{% for customer in customers %}
<tr>
<td>{{customer.first_name}}</td>
<td>{{customer.number}}</td>
<td>
{% for destination in customer.destinations %}
{{destination.number}}<br />
{% endfor %}
</td>
<td>
{% for destination in customer.destinations %}
{{destination.did}}<br />
{% endfor %}
</td>
<td>
{% for destination in customer.destinations %}
{{destination.own}}<br />
{% endfor %}
</td>
<td>
{% for destination in customer.destinations %}
{{destination.created_date|humandatetime|safe}}<br />
{% endfor %}
</td>
<td>
{% for destination in customer.destinations %}
{% if destination.expire_date %}{{destination.expire_date|humandatetime|safe}}{% endif %}<br />
{% endfor %}
</td>
<td>
{% for destination in customer.destinations %}
{{destination.gateway or ''}}<br />
{% endfor %}
</td>
<td>
{% for destination in customer.destinations %}
{{destination.channel or ''}}<br />
{% endfor %}
</td>
<td>
{% for destination in customer.destinations %}
del<br />
{% endfor %}
</td>
<td><input type="hidden" value="{{customer.first_name}} {{customer.last_name}}"></td>
<td><a id="{{customer.id}}" class="user-delete-icon">delete</a></td>
</tr>
{% endfor %}
Also the function that get all my customers is this
customers = db.session.query(Users).filter_by(user_type='CUST').all()
I think the problem is the relationship type lazy but I can't get to fix it