How to get username from user id in template - django

This is probably a simple answer but I cant figure it out. I have a comment system on my blog. I need to get the username from the user id.
I get the id from which is a fk to the users table
{{child_comment.parent_userdata_id}}
Usually when I need to do this I just user .username but it doesn't seem to work in this case

The only way you can get object data from the database is to fetch it on the server-side.
Unfortunately, you can't do that on the live HTML template.
Django template is just for evaluating the pre-existing context data for better use.
So, filtering the username from user id in views (backend) and passing it via the context into the template is the only (and probably the best) option.

Assuming user login is required to comment, you can create a variable of user = request.user in your view function, now user variable has the instance of user and pass it as context in template. It would look like this
views.py
def view_function(request):
user = request.user
# do something
context = {
'user' : user,
}
return render(request, 'template.html', context)
template.html
<p>{{user.username}}</p>
reference

Related

Show unique and viewable profile page for each user using Flask

I have created unique user pages for each person who registers to this social app by using the following:
#app.route("/profile/<username>", methods=["GET", "POST"])
def profile(username):
user = session["user"] or None
# grab the session user's username from db
username = mongo.db.users.find_one(
{"username": session["user"]})["username"]
user_profile = mongo.db.users.find_one({"username": user})
if session["user"]:
return render_template("profile.html", username=username, profile=user_profile)
return redirect(url_for("login"))
This creates a unique username profile built up from edited data that the user puts in. But I want to be able to view that profile from another user's login and then add them as a friend (if I choose).
Because I already have a URL created /profile/ do I need to create a new #app.route to something such as view_profile/<username>?
From there, I would use the Post and Get methods so if someone wanted to add that user as a friend they could click on that. From there, I think I would need the other user to accept the friend request? Not quite sure how to get to that just yet. But one step at a time I guess.
I started with the idea of a view_profile #app.route but now I am not 100% sure which direction to take it that will make the next stages also easy.

Create a User Profile or other Django Object automatically

I have setup a basic Django site and have added login to the site. Additionally, I have created a Student (Profile) model that expands upon the built in User one. It has a OneToOne relationship with the User Model.
However, I have yet not come right with forcing the user to automatically create a Profile the first time they log in. How would I make sure they are not able to progress through anything without creating this?
I have tried by defining the following in views:
def UserCheck(request):
current_user = request.user
# Check for or create a Student; set default account type here
try:
profile = Student.objects.get(user = request.user)
if profile == None:
return redirect('/student/profile/update')
return True
except:
return redirect('/student/profile/update')
And thereafter adding the following:
UserCheck(request)
at the top of each of my views. This however, never seems to redirect a user to create a profile.
Is there a best way to ensure that the User is forced to create a profile object above?
Looks like you're attempting to do something similar to Django's user_passes_test decorator (documentation). You can turn the function you have into this:
# Side note: Classes are CamelCase, not functions
def user_check(user):
# Simpler way of seeing if the profile exists
profile_exists = Student.objects.filter(user=user).exists()
if profile_exists:
# The user can continue
return True
else:
# If they don't, they need to be sent elsewhere
return False
Then, you can add a decorator to your views:
from django.contrib.auth.decorators import user_passes_test
# Login URL is where they will be sent if user_check returns False
#user_passes_test(user_check, login_url='/student/profile/update')
def some_view(request):
# Do stuff here
pass

Prompting registration after creating content but before save

I am trying to implement a page using Django where the user is able to create content, hit submit, and then is prompted to register or login if they are not currently logged-in. One of the fields in the model for the content references the user, so they must be logged-in to create it, however I want them to be able to input all of the data before they are prompted with logging-in. I have used the #loginrequired decorator on the view, but that forced the user to be logged-in before they create the content. Here is the view currently:
def search(request):
form = LocationInput()
if request.method == "POST":
form = LocationInput(request.POST)
if form.is_valid():
t = Trip(trip_name = form.cleaned_data['city'])
t.user = request.user
t.save()
form.save()
l = Location.objects.get(google_id=form.cleaned_data['google_id'])
l.trips.add(t)
l.save()
return HttpResponseRedirect('/trips/')
return render(request, 'frontpage/search.html', {'form': form})
It loads the form, creates an object that needs a user associated with it so I need to register the user but keep the data from LocationInput(request.POST) until after the user has registered. Any help would be greatly appreciated!
I can see two options:
Allow NULL for user reference, save the content in a state "pending user login or sign up", and store the ID of the content object in a session. Vacuum "old" contents with no user reference on a regular basis.
Save the whole data of the form in a session.
I like the first one better since you, as a superuser, have access to the content even if the user didn't login or signup, and if the user contact you later telling you he had troubles signing in, you will be able to help and recover the content he submitted. While if everything is stored in session, once the session is deleted, it's all lost.

Fallback for Django view that relies on session variable

I have a view that looks like this:
def CineByCiudad(request):
city = request.session["ciudad"]
cines = Cine.objects.filter(ciudad=city)
context = {'cines': cines}
return render_to_response('cine-ciudad.html', context, context_instance=RequestContext(request))
Now, I am using the session variable "ciudad" to filter my query.
On the homepage of my site I let the user set their "ciudad" and once its set I redirect them to another page and they can start viewing the content based on their city("ciudad").
My homepage checks if the session has items:
def index(request):
#Checks to see if the session has items, in particular if a city has been set
if not request.session.items():
return render_to_response('index.html', context_instance=RequestContext(request))
else:
return redirect(Cartelera)
Now lets suppose for some reason the user deletes his cookies and on the site he visits a url different than the homepage(something like www.site.com/cartelera) he would then get an error because the session variable "ciudad" is not set.
Is there a way to create a default value for this session variable in case that it has not been set?
Or what is a good practice to deal with this issue?
Use the dict.get method on the session to retrieve a default if the value isn't set, like this:
city = request.session.get('ciudad', 'default value')

Django Overwrite form data saved

I've posted about this problem before, but I still haven't found a solution so I'm hoping I'll have better luck this time.
I have a form that takes inputted data by the user. In another page, I am creating the identical form that the user has populated (pre-filled with that information) for editing purposes. Users will come to this page to EDIT the information they have already put in. My problem is that it isn't overwriting the instance.
def edit(request):
a = request.session.get('a', None)
if a is None:
raise Http404('a was not found')
if request.method == 'POST':
form = Name_Form(request.POST, instance=a)
if form.is_valid():
j = form.save( commit=False )
j.save()
else:
form = Name_Form( instance = a )
For this form, I'm using "unique_together" for some of the values. I'm also calling on `{{ form.non_field_errors }} in the template.
What is happening is when I make changes in the editing view, if the fields changes involves those defined in "unique_together" then an error is returned telling me that the instance already exists. Otherwise it saves a new instance. It isn't OVERWRITING.
Note that the reason i am using unique_together is that I want to prevent users from initially inputting the same form twice (before the editing stage, in the initial inputting view).
Any ideas?
EDIT: note that "a" refers to a session that includes a drop down box of all the available instances. This carried forward will indicate which instance the user wants to edit.
`
Why not do a database lookup of the model your trying to save and pull the fields from the form to the model then save the model?
Instead to store model a in session you should store it on database. Then edit it:
def edit(request, pk):
a = A.objects.get( pk = pk)
...
pk it the a identifier, you can send it to view via urls.py. I encourage to you to use POST/Redirect/GET pattern.
You can add a 'state' field on your model to control workflow (draft, valid)
You should not save objects in the session. If you really need to use a session - save a PK there and retrieve object right before giving it to Form. But the better solution is to send it in GET or POST parameters or included in url. Sessions are unreliable, data inside it can be destroyed between user's requests.
And you can retrieve value from a session in a more pythonic way:
try:
a = request.session['a']
except KeyError:
raise Http404('a was not found')