Django - User session display user data - django

I would like to display the list of entries where the user.username foreignKey is egal to session username. I want to display the specific data related to a session user only.
models.py:
from django.db import models
class User(models.Model):
username = models.CharField(max_length=10)
email = models.EmailField(verbose_name='e-mail')
date_signed = models.DateTimeField('date signed')
class ezMap(models.Model):
map_name = models.CharField(max_length=50, )
user = models.ForeignKey(User)
views.py:
from django.shortcuts import *
from ezmapping.models import *
def listEzMap(request):
#really not sure how to do it...
username = request.session['username']
user_list = ezMap.objects.get(map_name = username)
return render_to_response("map_list.html", {'user_list': user_list})
map_list.html template:
{% extends "base.html" %}
{% block content %}
<div class="list">
<h2> Map list </h2>
{% for object in user_list %}
<li>{{ object.map_name }}</li>
{% endfor %}
</div>
{% endblock %}
Thank you for your help with this!

views.py:
def listEzMap(request):
user_list = ezMap.objects.filter(user=request.user)
return render_to_response("map_list.html", {'user_list': user_list})

You can always access the logged in user from request as user = request.user, then use that user information to take decisions on user basis:
user = request.user
user_list = ezMap.objects.get(map_name = user.username)
You should check django authtication system as mentioned by dm03514 in comment.

Related

Querying model field data in template/views without get_object_or_404()

Homefeed is the page where i query all the blogposts
In this project, any user that sees a blogpost that they are interest in can submit their interest to the post. 1 user can only submit 1 interest to that blogpost, but they can submit as many interest as they want to different blogposts.
Right now in my home.html, I am trying to make it such that if YOU have submitted interest,(aka your interest status is at pending or accept or decline) for that particular blog post, you will see the view interest button instead of the submit interest button.
But I am facing a problem because in my views, I am querying for blog_posts = BlogPost.objects.all() and not blog_post = get_object_or_404(BlogPost, slug=slug). As such, how am I able to query whether or not for the particular blogpost, the user has already submitted an interest in my template to determine which button should show in my home.html? Thanks, and also I dont want to change the url at all :)
views.py
def home_feed_view(request, *args, **kwargs):
context = {}
blog_posts = BlogPost.objects.all()
context['blog_posts'] = blog_posts
page = pageFilter(request.GET, queryset=BlogPost.objects.exclude(author_id=request.user.id).order_by('date_updated'))
context['page'] = page
paginated_page = Paginator(page.qs, 4)
page = request.GET.get('page')
page_obj = paginated_page.get_page(page)
context['page_obj'] = page_obj
return render(request, "HomeFeed/snippets/home.html", context)
home.html
{% for post in page_obj %}
{% if post.interest_set.exists and request.user.is_authenticated %}
<a class="btn btn-info btn-sm" href="{% url 'HomeFeed:submitinterest' post.slug %}">View Interest</a>
{% else %}
<a class="btn btn-warning btn-sm" href="{% url 'HomeFeed:submitinterest' post.slug %}">Submit Interest</a>
{% endif %}
{% endfor %}
urls.py
path('', home_feed_view , name= "main"),
models.py
class Account(AbstractBaseUser):
email = models.EmailField(verbose_name="email", max_length=60, unique=True)
username = models.CharField(max_length=30, unique=True)
class BlogPost(models.Model):
title = models.CharField(max_length=50, null=False, blank=False, unique=True)
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
slug = models.SlugField(blank=True, unique=True)
class Interest(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
blog_post = models.ForeignKey(BlogPost, on_delete=models.CASCADE)
class InterestInvite(models.Model):
ACCEPT = "ACCEPT"
DECLINE = "DECLINE"
PENDING = "PENDING"
STATUS_CHOICES = [
(ACCEPT, "accept"),
(DECLINE, "decline"),
(PENDING, "pending"),
]
interest = models.OneToOneField(Interest, on_delete=models.CASCADE, related_name="interest_invite")
status = models.CharField(max_length=25, choices=STATUS_CHOICES, default=PENDING)
objects= models.Manager
views.py
type = TypeFilter(request.GET, queryset=BlogPost.objects.exclude((Q(author_id__in=request.user.blocked_users.all()) | Q(author = request.user))).order_by('date_updated')).annotate(user_has_interest=Case(When(interest__user=request.user, then=Value(True)), default=False, output_field=BooleanField()))
Using Django filters:
filters.py
class TypeofIdeaFilter(django_filters.FilterSet):
title = django_filters.CharFilter(field_name="title", lookup_expr='icontains')
class Meta:
model = BlogPost
You can annotate a field on your query:
from django.db.models import Case, When, Value, BooleanField
blog_posts = BlogPost.objects.all().annotate(
user_has_interest=Case(When(interest__user=request.user, then=Value(True)), default=False, output_field=BooleanField())
)
Now you can check in your template using if-else:
{% if post.user_has_interest %}
Something
{% else %}
Something else
{% endif %}
As Pierre mentioned template tags also achieve this (alternate for annotate answerd by Abdul).
Firstly create the file structure. Go into the app directory where the tag is needed, and add these files:
templatetags
templatetags/__init__.py
templatetags/blog_tags.py
The templatetags/blog_tags.py file:
from django import template
register = template.Library()
#register.simple_tag
def interest_submitted(blog_id, user_id):
if Interest.objects.filter(blog_post__id=blog_id, user_id=user_id).exists():
return True
else:
return False
In the template:
{% load blog_tags %} <!--don't forget to load the blog_tags.py file in the template. -->
{% for post in page_obj %}
{% interest_submitted post.id request.user.id as result %}
{% if result and request.user.is_authenticated %}
<a class="btn btn-info btn-sm" href="{% url 'HomeFeed:submitinterest' post.slug %}">View Interest</a>
{% else %}
<a class="btn btn-warning btn-sm" href="{% url 'HomeFeed:submitinterest' post.slug %}">Submit Interest</a>
{% endif %}
{% endfor %}
You can use a try instead of get_object_or_404(). That way you can use different logic and return different contexts if the object does not exist
pseudocode:
context = {}
try:
blog_posts = BlogPost.objects.all()
...
context = "Something"
return render(request, "HomeFeed/snippets/home.html", context)
except BlogPost.DoesNotExist:
context = "Something else"
return render(request, "HomeFeed/snippets/home.html", context)

Fetch complete user record in DJango

Below is the user record present in MySQL Database table - auth_user
Please click the image if it is not clear here
Below is my code present in View.py file.
from django.contrib.auth.models import User
from django.http import HttpResponse
from django.views import View
class loginController(View):
def get(self, request):
userobj = User.objects.filter(username = 'username')
return HttpResponse(request.POST.get('username'));
It returns just the username. Can you please suggest that why it just fetch the username and not the complete record?
Please let me know if you need more info
It returns the list of user objects represented by username. You can access all the properties of object as (obj.property). eg: if you have first_name in your user model
u = userobj.first()
u.first_name
u.last_name
If you want to fetch the complete user information, then you have to return User object, so that you can iterate throught that User object in your template
Example:-
Views.py
from django.views import generic
class loginController(generic.ListView):
template_name = 'project_app/user-list.html'
model = User
def get_queryset(self):
userlist = User.objects.all()
return userlist
project_app/user-list.html
{% if object_list %}
{% for user in object_list %}
<p>{{ user.username }}</p>
<p>{{ user.first_name }}</p>
{% endfor %}
{% endif %}

Django form not working for ManyToMany (auth.users) [duplicate]

This question already has an answer here:
Why doesn't save() automatically call save_m2m()?
(1 answer)
Closed 6 years ago.
I'm trying to create a Debt model using Django. It has a debtors field which link a debt to many users.
It behaves the way I want through Django's administration panel, but I can't get it to work using a django form. I can create debts but the the debtors field is emptying, despite the browser showing an accurate list of users to choose from.
What's even more surprising is that I thought that using blank=False in the model definition shouldn't allow that.
models.py:
from django.db import models
from django.utils import timezone
class Debt(models.Model):
author = models.ForeignKey('auth.User', related_name='author')
name = models.CharField(max_length=200)
amount = models.FloatField()
debtors = models.ManyToManyField('auth.User', blank=False)
invoice = models.FileField(blank=True)
created_date = models.DateTimeField(default=timezone.now)
def __str__(self):
return self.name
forms.py:
from django import forms
from .models import Debt
class NewDebtForm(forms.ModelForm):
class Meta:
model = Debt
fields = ('name', 'amount', 'invoice', 'created_date', 'debtors')
views.py:
from django.shortcuts import render, redirect
from .models import Debt
from .forms import NewDebtForm
def debt_list(request):
if request.method == "POST":
form = NewDebtForm(request.POST)
if form.is_valid():
debt = form.save(commit=False)
debt.author = request.user
debt.save()
debts = Debt.objects.order_by('created_date')
form = NewDebtForm()
return render(request, 'debt_share/debt_list.html',
{'debts': debts,
'form': form})
debt_list.html:
{% extends 'debt_share/base.html' %}
{% block content %}
{% for debt in debts %}
<h1>{{ debt.name }}</h1>
<h2>payƩ par {{ debt.author }}</h2>
<h2>{{ debt.amount }} {{ debt.invoice }}</h2>
<p>
Concerne
{% for user in debt.debtors.all %}
{{ user }}
{% endfor %}
</p>
{% endfor %}
<form method="POST">{% csrf_token %}
{{ form.as_p }}
<button type="submit">Save</button>
</form>
{% endblock content %}
When using ModelForms for many-to-many relationships, and use form.save(commit=False), you have to also call form.save_m2m(). Many-to-many relationships have to be saved in a second step, after the original object has been created; otherwise, its ID would not be known.
For more details, refer to the explanation in the docs: https://docs.djangoproject.com/en/1.10/topics/forms/modelforms/#the-save-method

Django + ndb/GAE: can't figure out how to properly display results from queries

I'm on a Google App Engine application, and I'm using django for views, templates, and file structure, and ndb for models/queries/dealing with the datastore.
My problem is that I can't figure out how to properly display a model via a query. It seems like I'm able to post to the datastore and retrieve from it alright, but I can't print what I've retrieved. I get back a StringProperty() object, which I think the Django request handler can't decipher, so it literally just prints "StringProperty()". Either that, or I just don't understand ndb queries as well as I think :)
Anyway, any ideas as to how I can make it show up correctly? Am I doomed for trying to combine ndb and django like this?
How it shows up:
http://imgur.com/yVDBe3T
In models.py:
from google.appengine.ext import ndb
# Create your models here.
class Contact(ndb.Model):
name = ndb.StringProperty
address_street = ndb.StringProperty
address_extra = ndb.StringProperty
address_city = ndb.StringProperty
address_state = ndb.StringProperty
address_zipcode = ndb.StringProperty
email = ndb.StringProperty
phone = ndb.StringProperty
In views.py:
from django import http
from django.core.context_processors import csrf
from django.views.decorators.csrf import csrf_protect
from django.template import RequestContext
from django.shortcuts import render_to_response
from models import Contact
def home(request):
contacts = Contact.query().fetch()
return render_to_response('index.html', {'message':'Hello World', 'contacts':contacts})
def form(request):
c = RequestContext(request)
if request.method == 'POST':
contact = Contact()
contact.name = request.POST['name']
address_street = request.POST['street']
address_extra = request.POST['extra']
address_city = request.POST['city']
address_state = request.POST['state']
address_zipcode = request.POST['zipcode']
email = request.POST['email']
phone = request.POST['phone']
contact.put()
return render_to_response('form.html', {'message':'Your contact, ' + contact.name + ', has been added.'}, c)
else:
return render_to_response('form.html', {'message':'Form!'}, c)
In index.html:
{% extends "base.html" %}
{% block pagestyle %}
{% endblock %}
{% block content %}
{{ message }}
<br><br>
<table border=1>
<tr>
<td>Name</td><td>Address</td><td>City</td><td>State</td><td>Zipcode</td><td>Email</td><td>Phone</td>
</tr>
{% for contact in contacts %}
<tr>
<td>{{ contact.name }}</td>
</tr>
{% endfor %}
</table>
<div class="button" value="/form">Add a contact</div>
{% endblock %}
You model definition is incorrect. You are not creating properties, just holding references to the Property class, it should be
class Contact(ndb.Model):
name = ndb.StringProperty()
address_street = ndb.StringProperty()
address_extra = ndb.StringProperty()
address_city = ndb.StringProperty()
address_state = ndb.StringProperty()
address_zipcode = ndb.StringProperty()
email = ndb.StringProperty()
phone = ndb.StringProperty()
And thats why you are seeing StringProperty in the output.

Django comparing lists and filtering objects

We want to display all of the pics on our site to a user. In another page we show the user the pics he/she has liked.
After reviewing the functionality it does not make sense for a user to see photos they have already liked in displayallpics.html.
We would like to filter out any pictures that a user has liked and only display photos a user has not liked in displayallpics.html:
Here's the sql for what we want to do:
select * from alphart_picdetails where id not in (select picture_id from alphart_like where user_id = 4);
user_id = the user which is logged in -- we just can't get django to do it.
Thanks for your help.
models.py
class PicDetails(models.Model):
poster = models.ForeignKey(User)
Title = models.CharField(max_length=50)
date = models.DateField(("Date"), auto_now_add=True)
def __unicode__(self):
return self.Title
class Like(models.Model):
user = models.ForeignKey(User)
picture = models.ForeignKey(PicDetails)
created = models.DateTimeField(auto_now_add=True)
votes = models.IntegerField()
views.py
def findpics(request): #designed to return all pics posted on the site -the pics user has liked
like_list = Like.objects.filter(user=request.user)
user = request.user
user_list = PicDetails.objects.filter(like=69)
return render_to_response("displayallpics.html", {'user_list':user_list, 'like_list':like_list, 'user':user})
template displayallpics.html:
{% for object in user_list %}
{{ object.Title }}
{% endfor %}
You can try this:
non_liked_pics = PicDetails.objects.exclude(like__user=request.user)
liked_pics = PicDetails.objects.filter(like__user=request.user)
and in the template,
{% for pic in non_liked_pics %}
{{ pic.picture.Title }}
{% endfor %}
{% for pic in liked_pics %}
{{ pic.picture.Title }}
{% endfor %}
Documentation here
Just make sure you send the variables in the context