Django URL user id versus userprofile id problem - django

I have a mini comunity where each user can search and find another user's profile.
Userprofile is a class model, indexed differently compared to user model class (user id is not equal to userprofile id).
But I cannot see a user profile by typing in the URL the corresponding id. I only see the profile of the currently logged in user.
Why is that?
I'd also want to have in my URL the username (a primary key of the user table also) and NOT the id (a number).
The guilty part of the code is:
What can I replace that request.user with so that it will actually display the user I searched for, and not the currently logged in?
def profile_view(request, id):
u = UserProfile.objects.get(pk=id)
cv = UserProfile.objects.filter(created_by = request.user)
blog = New.objects.filter(created_by = request.user)
return render_to_response('profile/publicProfile.html',
{
'u':u,
'cv':cv,
'blog':blog,
},
context_instance=RequestContext(request))
In file urls.py (of the accounts app):
url(r'^profile_view/(?P<id>\d+)/$',
profile_view,
name='profile_view'),
And in template:
<h3>Recent Entries:</h3>
{% load pagination_tags %}
{% autopaginate list 10 %}
{% paginate %}
{% for object in list %}
<li>{{ object.post }} <br />
Voted: {{ vote.count }} times.<br />
{% for reply in object.reply_set.all %}
{{ reply.reply }} <br />
{% endfor %}
<a href=''> {{ object.created_by }}</a> <br />
{{object.date}} <br />
Vote this
Comment </li>
{% endfor %}

Replace
cv = UserProfile.objects.filter(created_by = request.user)
blog = New.objects.filter(created_by = request.user)
With
#u is UserProfile.objects.get(pk=id)
cv = UserProfile.objects.filter(created_by = u)
blog = New.objects.filter(created_by = u)

Related

How to pass db info to html template to query db in Flask [duplicate]

I'm working with flask and have a html page that contains of user name(user.html) which took from table, Now How can I see more detail by clicking on each of users(which route to profile)?
I don't use login for app So I don't want to use g
app.py
# am I doing it right?
#app.route('/profile/<int:id>')
def profile(id=None):
detail = Contacts.query.get(id)
return render_template('profile.html', detail= detail , id=id)
user.html
{% extends "layout.html" %}
{% block content %}
<h2>show user</h2>
{% for contact in contact %}
# I got error when I click on each user name to see their 'profile'
#I guess because of id How can Solve it?
#error BuildError: ('profile', {}, None)
<strong>name:</strong><a href={{url_for('profile')}}>
{{ contact.name}}</a><br>
{% endfor %}
{% endblock %}
profile.html
{% extends "layout.html" %}
{% block content %}
<h2>show user profile</h2>
# how can I make it specific for each row of table(each user)?
{% for detail in Contacts %}
<strong>name:</strong> {{ detail.name}} <br>
<strong>email:</strong> {{ detail.email }} <br>
<strong>age:</strong> {{ detail.age}} <br>
<br>
{% endfor %}
{% endblock %}
model.py
class Contacts(db.Model):
__tablename__ = "Contacts"
id = db.Column(db.Integer, primary_key = True)
name = db.Column(db.String(50))
email = db.Column(db.String(50))
age = db.Column(db.Integer)
submit = SubmitField("Submit")
I noticed two things in your code:
# this
<a href={{url_for('profile')}}>
# should be
<a href={{url_for('profile', id=contact.id)}}>
# otherwise Flask can't find the route, because it needs an id
And the other one:
{% for detail in Contacts %}
There is no such thing as a Contacts variable in your template, because your view function does not send it. Just get rid of the loop and use detail directly, because it's what you sent to the template.

In django, how to use another model data from function based views

So I have a form that updates a key_instance object with a borrower. Currently my app needs the user to enter the name of the borrower, but I want it to display a dropdown list of data from another model the user model to select from, is there anyway to do this in a class based view? Here are my views.py and my template. What I was thinking is that I would like to use a get_list_or_404 on the user model and display it as a drop down list in the template and use that selection to populate the form field.
I manged to get the dropdown list to display in my template but I'm not sure as to how to save that value in my views.
Does anyone know if this is the right way or if this is doable? Thank you!!
views.py
def submit_key_request(request, pk):
"""
View function for renewing a specific keyInstance by admin
"""
key_inst=get_object_or_404(KeyInstance, pk=pk)
names = get_list_or_404(Users)
# If this is a POST request then process the Form data
if request.method == 'POST':
# Create a form instance and populate it with data from the request (binding):
form = UpdateKeyForm(request.POST)
# Check if the form is valid:
if form.is_valid():
# process the data in form.cleaned_data as required (here we just write it to the model due_back field)
key_inst.is_requested = True
key_inst.status = 'r'
key_inst.date_requested = datetime.date.today()
key_inst.borrower = form.cleaned_data['borrower']
key_inst.save()
# redirect to a new URL:
return HttpResponseRedirect(reverse('all-available-keys') )
# If this is a GET (or any other method) create the default form.
else:
form = UpdateKeyForm(initial={'borrower': 'N/A'})
return render(request, 'catalog/keyinstance_request_update.html', {'form': form, 'keyinst':key_inst})
template
{% extends "base_generic.html" %}
{% block content %}
<div class="wrapper">
<div class="centered"> <h1>Request Keys For Room: {{keyinst.roomkey}}</h1></div>
<div class="square-box">
<div class="square-content">
<form action="" method="post" >
{% csrf_token %}
<table style="display: inline-flex">
{{ form}}
</table>
<select name = 'name'>
{% for name in names %}
<option value="{{ name }}">{{ name }}</option>
{% endfor %}
</select>
<p>
(Please use their login name i.e. <b>{{ user.get_username }}</b>)
</p>
<p><input required id="checkBox" type="checkbox" onclick="validate()"> I accept the terms and conditions</p>
<p id="text" style="display:none">You Have Agreed To the Terms and Conditions</p>
<input type="submit" value="Submit" />
</form>
</div>
</div>
</div>
{% endblock %}
Here is how I manged to do it, Not sure if this is the best 'pythonic' or best practice. Please let me know if it's not.
my views.py
def submit_key_request(request, pk):
"""
View function for renewing a specific keyInstance by admin
"""
key_inst=get_object_or_404(KeyInstance, pk=pk)
names = get_list_or_404(User)
# If this is a POST request then process the Form data
if request.method == 'POST':
name = request.POST['name']
key_inst.is_requested = True
key_inst.status = 'r'
key_inst.date_requested = datetime.date.today()
key_inst.borrower = name
key_inst.save()
return HttpResponseRedirect(reverse('all-available-keys') )
# If this is a GET (or any other method) create the default form.
else:
pass
return render(request, 'catalog/keyinstance_request_update.html', {'keyinst':key_inst, 'names':names})
template
{% extends "base_generic.html" %}
{% block content %}
<div class="wrapper">
<div class="centered"> <h1>Request Keys For Room: {{keyinst.roomkey}}</h1></div>
<div class="square-box">
<div class="square-content">
<form action="" method="post" >
{% csrf_token %}
</br>
<select name = 'name' required>
{% for key in names %}
<option value="{{ key }}">{{ key }}</option>
{% endfor %}
</select>
<p>
(Please use their login name i.e. <b>{{ user.get_username }}</b>)
</p>
<p><input required id="checkBox" type="checkbox" onclick="validate()"> I accept the terms and conditions</p>
<p id="text" style="display:none">You Have Agreed To the Terms and Conditions</p>
<input type="submit" value="Submit" />
</form>
</div>
</div>
</div>
{% endblock %}

Django Admin Action using intermediate page

I have a model with a lot of fields. I only have a few fields I that I want to be required. So instead of the change list super long, I want to have a short change list then have admin actions that can give predefined subsets of the fields.
The initial action takes me to the correct page but when I submit the form it returns me to whatever page I designate, but doesn't update the fields. I am okay with tearing this down starting over again if needed. I think what I really need to know, what do I put in the action="" portion of the html to have the recursion work properly?
I am using django 1.7. I have to obfuscate a lot of my fields as a cya thing since I am working in a heavily information secure field.
Here is my admin.py
class CredentialAdmin(admin.ModelAdmin):
fields = ['reservedBy','reserveto']
list_display = ['reservedBy','reserveto']
class reserveToFormAdmin(forms.Form):
reservedBy = forms.CharField(widget=forms.Textarea, max_length=50)
reserveto = forms.DateTimeField(widget=forms.DateTimeInput)
def reserveCred(self, request, queryset):
form = None
plural = ''
if 'submit' in request.POST:
form = self.reserveToFormAdmin(request.POST)
for f in form.fields:
print f
print form.is_valid()
print form.errors
if form.is_valid():
reservetos = form.cleaned_data['reserveto']
reservedBys = form.cleaned_data['reservedBy']
print "hello"
count = 0
for cred in queryset:
cred.reserveto = reservetos
cred.reservedBy = reservedByss
cred.save()
count += 1
if count != 1:
plural = 's'
self.message_user(request, "Successfully reserved %s cred%s." % (count, plural))
return HttpResponseRedirect(request.get_full_path(),c)
if not form:
form = self.reserveToFormAdmin(initial={'_selected_action' : request.POST.getlist(admin.ACTION_CHECKBOX_NAME)})
return render(request,'admin/reserveCreds.html',{'creds':queryset, 'form':form, 'path':request.get_full_path()})
reserveCred.short_description = "Reserve Selected Creds"
actions = [check_out_a_cred,check_in_a_cred,audit_creds,CompareAudits,reserveCred]
reserveCreds.html
{% extends "admin/base_site.html" %}
{% block content %}
<p>How long and which department to reserver creds:</p>
<form action="{{ path }}" method="post">{% csrf_token %}
{{ form }}
<input type="submit" name="submit" value="submit" />
<input type="button" value = "Cancel" />
</form>
<h2> reserving: </h2>
<ul>
{% for cred in creds %}
<li> {{ cred.userid }} </li>
{% endfor %}
</ul>
{% endblock %}

Django 1.5 Creating multiple instances of model in ModelAdmin

I'm kind of puzzled with this task:
I have 2 tables: User, Codes
I want to generate randomly codes in a specific pattern.
I've already written that part as a function, but it's hard to implement the function
in the ModelAdmin.
So I would be very pleased if someone knows a trick to accomplish this.
It would be enough to have a button in the User form to envoke the function, which then creates these codes.
But how do I implement such a button?
Is there a way to to this?
EDIT: typo
SOLUTION:
Since I want to generate vouchers for a particular user I can edit the admin.py like this:
class MyUserAdmin(UserAdmin):
def vouchers(self, obj):
return "<a href='%s'>Generate vouchers</a>" % reverse(gen_voucher_view, kwargs={'user':obj.pk,})
vouchers.allow_tags = True
list_display = (..., 'vouchers')
which represents a clickable link in the admin view of my User model.
Now I connect the link to my view in urls.py by adding
url(r'admin/gen_vouchers/(?P<user>\w+)/$', gen_voucher_view, name='gen_voucher_view')
to urlpatterns.
For creating the vouchers I provide a form in forms.py
class VoucherGeneratorForm(forms.Form):
user = forms.CharField(User, required=True, widget=forms.HiddenInput())
amount = forms.IntegerField(min_value=0, max_value=500, required=True)
readonly = ('user', )
In views.py I'm adding my view function:
#login_required
def gen_voucher_view(request, user):
if request.method == 'POST': # If the form has been submitted...
form = VoucherGeneratorForm(request.POST) # A form bound to the POST data
if form.is_valid(): # All validation rules pass
# GENERATE vouchers here by using form.cleaned_data['amount']
# and user (generate_vouchers is a self defined function)
vouchers = generate_vouchers(user, form.cleaned_data['amount']
# set error or info message
if len(vouchers) == form.cleaned_data['amount']:
messages.info(request, "Successfully generated %d voucher codes for %s" % (form.cleaned_data['amount'], user))
else:
messages.error(request, "Something went wrong")
u = User.objects.get(pk=user)
form = VoucherGeneratorForm(initial={'user':user}) # An unbound form
return render_to_response('admin/codes.html', {'request': request, 'user':user, 'form':form, 'userobj': u}, context_instance=RequestContext(request))
else:
form = VoucherGeneratorForm(initial={'user':user}) # An unbound form
Last but not least create a template admin/codes.html where my form is displayed:
{% extends "admin/base_site.html" %}
{% load i18n admin_static static %}
{% block breadcrumbs %}
<div class="breadcrumbs">
{% trans 'Home' %}
›
{% trans 'Users' %}
›
{% trans 'Vouchercodes' %}
›
Voucher Generator
</div>
{% endblock %}
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% static "admin/css/dashboard.css" %}" />{% endblock %}
{% block content %}
<div id="content-main">
{% if request.user.is_active and request.user.is_staff or userobj and userobj.is_active and userobj.is_staff %}
<h1 id="generator_title">Generate vouchers for {{user}}</h1>
<form id="formular_generator" action="" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<table>{{ form }}</table>
<button id="generatebutton" type="submit" name="action" value="generate">Generate</input>
</form>
{% else %}
<p>{% trans "You don't have permission to access this site." %}</p>
</div>
{% endif %}
{% endblock %}
{% block sidebar %}
{% endblock %}
Done!
To export them in a pdf I used admin actions, as propsed by Sumeet Dhariwal below.
U mean that you need to run a script from within the admin ?
If so check out django-admin-tools
http://django-admin-tools.readthedocs.org/en/latest/dashboard.html
SOLUTION FOUND:
no that was not what i meant, because I want to generate vouchers for 1 particular user and not for more, but that's a good remark.

Django - Retrieve Unauthenticated User object

As the titles states, I have a need for users to retrieve User information of different users, whether or not they're authenticated.
I have a 'profile' template with some logic to either display static user information (for public) or editable user information (for the user it belongs to).
PROBLEM: The condition in my template is returning "true" - the User object appears to be authenticated BUT it's not. If I navigate from that page (profile) no user logged in.
I'm fairly new to Django. Am I not retrieving the User object correctly in my view.py?
views.py
def GetProfileById(request, userid):
try:
user = User.objects.get(pk=userid)
except User.DoesNotExist:
return HttpResponseRedirect('/')
try:
user_profile = user.get_profile()
except Exception:
return HttpResponseRedirect('/')
context = {'user': user, 'user_profile': user_profile}
return render_to_response('profile.html', context, context_instance=RequestContext(request))
profile.html
{% if user.is_authenticated %}
<form id="form-about" class="form-horizontal" action="{% url update-user-profile %}" method="POST">
{% csrf_token %}
<p>{{ about_form.first_name }}</p>
<p>{{ about_form.last_name }}</p>
<p>{{ about_form.birthday }}</p>
<p>{{ about_form.profession }}</p>
<button class="btn btn-primary" type="submit">Save</button>
</form>
{% else %}
<p><b>Name:</b> {{ user.first_name }} {{ user.last_name }}</p>
<p><b>DOB:</b> {{ user_profile.birthday }}</p>
<p><b>Profession:</b> {{ user_profile.profession }}</p>
<p><b>Member since:</b> {{ user.date_joined|date:'Y-M-d' }}</p>
<p><b>Last login:</b> {{ user.last_login|date:'Y-M-d # H:i' }}</p>
{% endif %}
It seems like, what you're trying to do is, if a user is currently logged in, you want to show a form that lets them update a profile.
So the problem is:
In your view, you're setting user to a User object from the database.
This object does not represent or contain information about whether the current user is logged in. It's just the record from the database.
You want to check request.user, which represents the User object for the user who requested the web page.
So in your template, change:
{% if user.is_authenticated %}
to:
{% if request.user.is_authenticated %}
I believe you're confusing user and request.user. The former is the user being displayed, the latter is the user that is currently logged in, or an AnonymousUser if no one is logged in.
You want to display that form if the user that is currently logged in and the user being displayed are the same, right? Then just change
{% if user.is_authenticated %}
To
{% ifequal user request.user %}