Flask, Join two models with foreign key - python

my two models are
class Users (db.Model):
UserId = db.Column(db.INTEGER, primary_key=True,autoincrement=True)
UserName = db.Column(db.String(25),nullable=False, unique=True)
Email = db.Column(db.String,nullable=False,unique=True)
plan = db.relationship(
'Messages',
collection_class=attribute_mapped_collection('language'),
cascade="all,delete"
)
class Messages (db.Model):
MessageId = db.Column(db.INTEGER,primary_key=True,autoincrement=True)
SenderId = db.Column(db.INTEGER,db.ForeignKey('Users.UserId'),nullable=False)
language = db.Column(db.Enum('de', 'en'), nullable=False)
Now, My view looks like:
def premium():
usr_obj = models.Users.query.join(models.Messages)\
.order_by(models.Users.UserId.desc())
return render_template('user_plan.html', user=usr_obj)
My user_html is like:
{% for a in user %}
{{ a.UserName }} </br> {{ a.SenderID }} </br>
{% endfor %}
It is giving me only value of {{ a.UserName }} and not of {{ a.SenderID }}, why??

if you want only senderId and UserName from this join,you can try this:
obj= Users.query.with_entities(Users.UserName,Messages.SenderId
).join(Messages,Messages.SenderId==Users.UserId
).order_by(Users.UserId.desc()
).all()
explanation:-
we are applying join on Messages.SenderId and Users.UserId
with_entities: it means we only want UserName, SenderId from this join.
you can use for loop to access UserName and SenderId from this join.
like this:
for o in obj:
print o.UserName,o.SenderId
i hope this is solution of your problem.Use it according to your problem case.

One can use:
{% for a in user %}
{{ a.UserName }} </br> {{ a.plan[g.current_lang].SenderID }} </br>
{% endfor %}

Related

Display unique values on flask jinja template

I have a query on my views.py:
query = db.session.query(Basket, Fruits).filter(Fruits.basket_id == Basket.id)
In the html template, I wish to display for each basket id (basket id here is unique), what are the fruits inside each basket, thus I used a nested for loop in my template.
I have tried on the html template:
{% for basket in query | unique %}
<p>{{ basket.Basket.id }}</p>
{% for fruits in query %}
<p>{% if basket.Basket.id == fruits.Basket.id %}
<p>{{ query.Fruits.fruit }}</p>
{% endif %}
{% endfor %}
But the unique basket id is not displayed.
I have thought of creating 2 queries so that I can put .distinct and display the unique basket id, then use the other query to display the fruits, but that didn't make sense to me because I still need all the information in the whole query. Beginner in flask btw.
You might be able to achieve that with a one to many relationship.
class Basket(db.Model):
id = db.Column(db.Integer, primary_key = True)
name = db.Column(db.String(100))
fruits = db.relationship('Fruit', backref='basket')
class Fruit(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100))
basket_id = db.Column(db.Integer, db.ForeignKey('basket.id'))
#app.route('/')
def baskets():
baskets = db.session.query(Basket).all()
return render_template('baskets.html', baskets=baskets )
Jinja2 Template:
{% for b in baskets %}
<ul>
<p>
{% b.name %}
</p>
{% for f in b.fruits %}
<li>{{ f.name }}</li>
{% endfor %}
</ul>
{% endfor %}

django-python create Multidimensional Array in views.py

In models.py:
class PUser(models.Model):
phone = models.TextField(blank=True, null=True)
email = models.TextField()
txt = models.TextField(blank=True, null=True)
I want to create Multidimensional Array for that.
For now this is what I have in the function in views.py:
def main(request):
users = []
for i in range (5):
for a in range(3):
users[i][a] = PUser.objects.all()
return render(request, 'main.html', {'users': users})
But I know its not correct, its not working.
How should I edit it?
And how the code in the main.html should be?
I was thinking about something like {{ users[2][3] }} for example. How the code should be? (I have read same questions but was not helpful for me)
Since PUser.objects.all() returns an array of PUser object, you just have to write :
def main(request):
users = PUsers.objects.all()
return render(request, 'main.html', {'users': users})
and in your template, iterate on users array :
{% for user in users %}
{{ user.phone }}
{{ user.email }}
{{ user.txt }}
{% endfor %}
If you wanna print a specific user, you can by specifying its index :
{{ users[3].phone }}
{{ users[3].email }}
{{ users[3].txt }}
# or
{{ users.3.phone }}
{{ users.3.email }}
{{ users.3.txt }}

How can I link the author of a post two his profile page with django?

I am trying to link the author of a post two his profile page, but when I click the on the link, get refered two /profiles/ not to the id of the author.
My views.py looks like this:
def userpage(request, id):
profil = get_object_or_404(UserProfile, pk=id)
context = {'profil': profil}
return render(request, 'gaestebuch/userpage.html', context)
My urls.py looks like this:
url(r'^profiles/(?P<id>[0-9]+)/$', views.userpage, name='userpage')
And the html part where I want to have the link looks like this:
{% for e in latest_eintrage_list %}
<li>
<div id="comment_main">
---> {{ e.author }}
<br>
</div>
{{ e.title }}
<br>
<div id="comment_main">
Comments: {{ e.comments.count }} | {{ e.created_date }} | {{ e.get_typ_display }}
</div>
{% if not forloop.last %}
<hr>
{% endif %}
</li>
{% endfor %}
The part marked with an arrow is the part, where I wanted the link to the author to be.
models.py:
class UserProfile(models.Model):
user = models.OneToOneField(User)
info = models.CharField(max_length=200, blank = False, default=('keine Angabe'))
class Eintrag(models.Model):
author = models.ForeignKey('auth.User')
title = models.CharField(max_length=200)
text = models.TextField()
NEED = 'ND'
GIVE = 'GV'
TYP_CHOICES = (
(NEED, 'Need'),
(GIVE, 'Give'),
)
typ = models.CharField(max_length=2, choices= TYP_CHOICES, default=NEED)
created_date = models.DateTimeField(default=timezone.now)
I am receving the following error-message:
Reverse for 'userpage' with arguments '('',)' and keyword arguments '{}' not found. 1 pattern(s) tried: [u'gaestebuch/profiles/(?P<id>[0-9]+)/$']
I am glad for any help :)
Inside the {% for e in latest_eintrage_list %} loop, you do have a variable profil. Therefore profil.id is treated as the empty string, and the url tag fails.
You can follow the foreign key from Eintrag.author foreign key to the User model, then follow the one to one field backwards to the UserProfile model:
{{ e.author }}

Generate a dynamic form using flask-wtf and sqlalchemy

I have a webapp that allows users to create their own fields to be rendered in a form later on.
I have a model Formfield like so:
class Formfield(db.Model):
id = db.Column(db.Integer, primary_key = True)
form_id = db.Column(db.Integer, db.ForeignKey('formbooking.id'))
label = db.Column(db.String(80))
placeholder_text = db.Column(db.String(80))
help_text = db.Column(db.String(500))
box_checked = db.Column(db.Boolean, nullable = True, default = False)
options = db.Column(db.String) # JSON goes here?
answer = db.Column(db.String)
required = db.Column(db.Boolean, nullable = False, default = False)
order = db.Column(db.Integer)
fieldtype = db.Column(db.Integer)
that I use to represent a field, whatever the kind (checkbox, input, more in the future).
As you can see, every field has a FK to a form_id.
I’m trying to generate a dynamic form for a given form_id.
The catch is that I need to determine the type of field to render for every Formfield.
So I also need to process the fieldtype at some point.
I guess a solution would be to somehow pass the form_id to a function in my Form class.
I have no clue how to do it or where to look for a solution.
Any help would be very appreciated!
I think I managed to create dynamic forms with the idea from here https://groups.google.com/forum/#!topic/wtforms/cJl3aqzZieA
you have to create a dynamic form at view function, fetch the form field you want to get, and iterate every field to construct this form object. I used for fieldtypes simple text instead of integer values. Since it seems easy to read at code level.
class FormView(MethodView):
def get(self):
class DynamicForm(wtforms.Form): pass
dform = main.models.Form.objects.get(name="name2")
name = dform.name
for f in dform.fields:
print f.label
setattr(DynamicForm , f.label, self.getField(f))
d = DynamicForm() # Dont forget to instantiate your new form before rendering
for field in d:
print field # you can see html output of fields
return render_template("customform.html", form=d)
def getField(self, field):
if field.fieldtype == "text":
return TextField(field.label)
if field.fieldtype == "password":
return PasswordField(field.label)
# can extend if clauses at every new fieldtype
for a simple form render jinja template 'forms.html'
{% macro render(form) -%}
<fieldset>
{% for field in form %}
{% if field.type in ['CSRFTokenField', 'HiddenField'] %}
{{ field() }}
{% else %}
<div class="form-group {% if field.errors %}error{% endif %}">
{{ field.label }}
<div class="input">
{% if field.name == "body" %}
{{ field(rows=10, cols=40) }}
{% else %}
{{ field() }}
{% endif %}
{% if field.errors or field.help_text %}
<span class="help-inline">
{% if field.errors %}
{{ field.errors|join(' ') }}
{% else %}
{{ field.help_text }}
{% endif %}
</span>
{% endif %}
</div>
</div>
{% endif %}
{% endfor %}
</fieldset>
{% endmacro %}
and customform.html is like this
{% extends "base.html" %}
{% import "forms.html" as forms %}
{% block content %}
{{ forms.render(form) }}
{% endblock %}

How do I retrieve timedate from the database and display in template?

I'm a complete Python and Django noob so any help is appreciated. This is what my model looks like:
class Matches(models.Model):
id = models.AutoField(primary_key=True)
date = models.DateTimeField()
court = models.ForeignKey(Courts)
class Participants(models.Model):
id = models.AutoField(primary_key=True)
match = models.ForeignKey(Matches)
userid = models.ForeignKey(User)
games_won = models.IntegerField()
This is what my view looks like:
def index(request):
latest_matches_list = Matches.objects.all()[:5]
return render_to_response('squash/index.html', {'latest_matches_list': latest_matches_list})
return HttpResponse(output)
And my template:
{% if latest_matches_list %}
{% for matches in latest_matches_list %}
{{ match.id }}
{% endfor %}
{% else %}
<p>No matches are available.</p>
{% endif %}
Two questions:
When I do Matches.objects.all() in the shell console it returns: [<Matches: Matches object>]. Why doesn't it print out the id and date?
In the template file I'm initially trying to test printing out the id of Matches but it doesn't seem to be working. What variable do I need for {{ match.id }}. The goal is to print out the following per match:
[matchid] [date] [time] [player1_wins] [player2_wins]
1 1-1-2011 20:00 6 8
1: how would it know to print id and date out of all fields you might have?
You can define what your object returns when printed by defining __unicode__
http://docs.djangoproject.com/en/dev/ref/models/instances/#django.db.models.Model.unicode
# ... model class
def __unicode__(self):
return "%s %s" % (self.id, self.date)
2: In your template, you iterate over latest_matches_list with the variable matches yet you use {{ match.id }} which isn't defined. Use {{ matches.id }}.
{% for matches in latest_matches_list %}
{{ match.id }} <!-- not defined -->
{{ matches.id }} <!-- this is your variable -->
{% endfor %}

Categories

Resources