how can show profile User in html django - django

i create user auth and make model profile user with signals to create profile like User
but i want show user profile in template
---- model
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
# Create your models here.
class profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
music = models.CharField(max_length=50)
skils = models.CharField(max_length=50)
search = models.CharField(max_length=50)
posts = models.CharField(max_length=50)
boi = models.TextField()
img = models.ImageField(upload_to="profile-img")
def __str__(self):
#return self.user or 'User'
return str(self.id)
def create_profile(sender, **kwargs):
if kwargs['created']:
user_profile = profile.objects.create(user=kwargs['instance'])
post_save.connect(create_profile, sender=User)
---- path
path('profile/<int:id>', views.profile, name="profile")
----- views
def profile(request, id):
ff = profile.objects.get(id=id)
context = {'ff' : ff}
return render(request, 'profile.html', context)
views not work i dont know the problem
in html...
{% url 'profile' profile.id %}
how can show profile User in html django

If you want User can show his Profile, you need to get the Profile object using the current user instance instead of profile id like this...
views.py
def profile(request):
ff = profile.objects.get(user=request.user) # This query object give logged in user profile
context = {'ff' : ff}
return render(request, 'profile.html', context)
Profile url path become like this
urls.py
path('profile/', views.profile, name="profile")
Html url becomes like this
{% url 'profile' %}
NOTE - No need pass id of profile because here we get profile of current user which is logged in

Related

Django : How do you check if an user has the rights on a pk value inserted in the URL - decorator

I am a newbee in django. In my website, when the user logs in, he is redirected to a page with a dropdown menu where he has to choose a contract on which he wants to work. After selecting the contract he is redirected to the specific homepage define with a ID in the url. The ID value comes from the ID of the contract in the database.
What
How can I check by a function or a decorator that the user has the rights to be on this contract. Because any user could right the numbers in the url and access to a page where he should not have access. By example, an user has the right to the contracts 109 and 144, so he can go on the urls "home/109" and "home/144", but if is change the value in the url to another one, he should not have access
Here is my view of the dropdown menu :
#authenticated_user
def selectcontrat(request) :
context = initialize_context(request)
form_client = SelectClient(request.POST, user=request.user)
if form_client.is_valid():
id_contrat = request.POST.get("ID_Customer")
return redirect(reverse('home', args=(id_contrat,)))
context['form_client'] = form_client
return render(request, 'base/selectcontrat.html', context)
Here the views of the home page :
#authenticated_user
def home(request, id_contrat=None):
context = initialize_context(request)
return render(request, 'home.html', context)
The urls :
from django.urls import path
from . import views
urlpatterns = [
path('home/<int:id_contrat>/', views.home, name="home"),
path('', views.loginAD, name="login"),
path('signin', views.sign_in, name='signin'),
path('callback', views.callback, name='callback'),
path('selectcontrat', views.selectcontrat, name='selectcontrat')
The model is the relation between a user and a group. which group the user has righs.
class Groups(models.Model):
ID = models.AutoField(primary_key=True) # Field name made lowercase.
IDCustomer = models.IntegerField(blank=True, null=True) # Field name made lowercase.
GroupName = models.CharField(max_length=255, blank=True, null=True) # Field name made lowercase.
CreatedOn = models.DateTimeField(blank=True, null=True) # Field name made lowercase.
class AADJNTGroup(models.Model):
ID = models.AutoField(primary_key=True)
ID_User = models.ForeignKey(User, on_delete=models.CASCADE)
ID_Group = models.ForeignKey(Groups, on_delete=models.CASCADE)
CreatedOn = models.DateTimeField(auto_now_add=True)
CreatedBy = models.CharField(max_length=255)
To do that, I tried to do a decorator, but I do not know how to get the id_contrac value that is redirected after the form. How can I get this value in a decorator, like that then I could check the rights on the database.
The decorator not working :
def check_pk(view_func) :
def wrapper_func(request, *args, **kwargs):
list_user_rights = AADJNTGroup.objects.filter(ID_group_id=args[0]).values_list('ID_User_id', flat=True)
print(list_user_rights)
return wrapper_func
Anyone has an idea ?
If using class based views you can use UserPassesTestMixin
from django.contrib.auth.mixins import UserPassesTestMixin
class MyView(UserPassesTestMixin, View):
def test_func(self):
return self.request.user.email.endswith('#example.com')
if using function views you can use the user_passes_test decorator.
from django.contrib.auth.decorators import user_passes_test
def email_check(user):
return user.email.endswith('#example.com')
#user_passes_test(email_check)
def my_view(request):
...
I did a decorator, that requests the different database to check the rights
Here is the decorator
def check_user_rights():
def wrapper_func(view_func):
#wraps(view_func)
def wrapper(request, *args, **kwargs):
# THE ID THAT I CAN COLLECT
ID_contrat = kwargs["id_contrat"]
User_ID = request.user.id
# THE SQL REQUEST TO GET THE VALUE
list_user_rights = AADJNTGroup.objects.filter(ID_User_id=User_ID).values_list('ID_Group_id', flat=True)
ID_contrat_list = list(list_user_rights)
Contrat_right = Groups.objects.all().filter(ID__in=ID_contrat_list).values_list('IDCustomer', flat=True)
# Compare the rights
if ID_contrat in Contrat_right :
return view_func(request, *args, **kwargs)
else :
return HttpResponse("<h1> page not found</H1>")
return wrapper
return wrapper_func

Integrity Error after submitting POST variables from ModelForm (extended User Model in Django)

I'm creating a staff registration page to create a new user (where NO one has logged in i.e. an Anonymous User). I have a Profile model (adding additional fields such as department, alias etc) which extends from the User model within Django. I've referenced User as a one-to-one relationship to Profile.
When a new staff registers, they have to specify their "stafftypeid" ("Job Title") from the ModelChoiceField referencing Staff_Type table. The User table doesn't store "stafftypeid", so I extended the UserCreationForm.
My problem is that I can successfully submit POST variables via the forms and the User (auth_user) will create a new record. I can see the new User within the Django /admin page. However, Profile will fail to create an accompanying new record and I receive an error ("IntegrityError at /register/
(1048, "Column 'staffTypeID' cannot be null")"). Strangely, I have all the POST variables, but the variables needed for the fields in Profile table are not being passed across.
Is this an inheritance problem? A new Profile record should only be created when you create a new User.
I've tried to follow tutorials and other code from Corey Schafer Django Tutorial 8, Simpleisbetterthancomplex (https://simpleisbetterthancomplex.com/tutorial/2016/07/22/how-to-extend-django-user-model.html#onetoone) and Stack Overflow.
I've also tried re-writing def form.save() and then split my forms into two (originally just one), since its supposed to be easier to handle on the database side. I'd be really grateful for advice here!
Administrator\models.py: (Staff_Type)
from django.db import models
from decimal import Decimal
class Staff_Type(models.Model):
stafftypeid = models.AutoField(db_column='staffTypeID', primary_key=True)
stafftypedesc = models.CharField(db_column='staffTypeDesc', max_length=150)
class Meta:
ordering = ['stafftypedesc']
unique_together = ('stafftypedesc',)
db_table = 'stafftype'
def __str__(self):
return self.stafftypedesc
Users\models.py:
from django.db import models
from django.contrib.auth.models import User
from decimal import Decimal
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
stafftypeid = models.ForeignKey('Administrator.Staff_Type', models.DO_NOTHING, db_column='staffTypeID')
employeeid = models.CharField(max_length=20)
alias = models.CharField(max_length=20)
department = models.CharField(max_length=150)
organization = models.CharField(max_length=150)
fte = models.DecimalField(max_digits=4, decimal_places=1, default=Decimal(100.0))
def __str__(self):
return f'{self.user.username} Profile'
Users\signals.py:
from django.db.models.signals import post_save
from django.contrib.auth.models import User
from django.dispatch import receiver
from .models import Profile
#receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
#receiver(post_save, sender=User)
def save_profile(sender, instance, **kwargs):
instance.profile.save()
Users\register.html:
{% extends "Administrator/adminBase.html" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="col-md-8">
<div class="content-section">
<form method="POST">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Register New User </legend>
{{ user_form|crispy }}
{{ profile_form|crispy }}
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" type="submit">Sign Up</button>
</div>
</form>
</div>
</div>
{% endblock content %}
Users\forms.py:
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
from Administrator.models import Staff_Type
from .models import Profile
from .models import Profile
from django.utils.translation import ugettext_lazy as _
class UserRegisterForm(UserCreationForm):
email = forms.EmailField(max_length=150, label = "Email")
first_name = forms.CharField(max_length=150, label = "First Name")
last_name = forms.CharField(max_length=150, label = "Surname")
class Meta:
model = User
fields = ['username', 'email', 'first_name', 'last_name', 'password1', 'password2']
class ProfileForm(forms.ModelForm):
stafftypeid = forms.ModelChoiceField(queryset=Staff_Type.objects.all(), empty_label="Staff Type")
employeeid = forms.CharField(max_length=20, label="Employee ID")
alias = forms.CharField(max_length=20, label="Alias")
department = forms.CharField(max_length=150, label="Department")
organization = forms.CharField(max_length=150, label="Organization")
fte = forms.DecimalField(max_digits=4, decimal_places=1, min_value=0.0, max_value=100.0, label="FTE(%)")
class Meta:
model = Profile
fields = ['stafftypeid', 'employeeid', 'alias', 'department', 'organization', 'fte']
Users\views.py:
from django.shortcuts import render, redirect
from django.contrib import messages
from .forms import UserRegisterForm, ProfileForm
def register(request):
if request.method == "POST":
user_form = UserRegisterForm(request.POST)
profile_form = ProfileForm(request.POST)
if user_form.is_valid() and profile_form.is_valid():
user_form.save()
profile_form.save()
username = user_form.cleaned_data.get('username')
stafftypeid = profile_form.cleaned_data.get('stafftypeid')
messages.success(request, f'Account created for {username}, with alias: {stafftypeid}')
return redirect('admin-home')
else:
user_form = UserRegisterForm()
profile_form = ProfileForm()
return render(request, 'users/register.html', {'user_form': user_form, 'profile_form': profile_form})
Users\apps.py:
from django.apps import AppConfig
class UsersConfig(AppConfig):
name = 'users'
def ready(self):
import users.signals
The error is happening in your signal. There you just create a Profile and only set the user field, you don't set any of the other fields.
You don't need this signal. You are creating the profile in the separate Profile form and saving it in the view. You should remove both those signals.
Then, update the view:
if user_form.is_valid() and profile_form.is_valid():
user = user_form.save()
profile = profile_form.save(commit=False)
profile.user = user
profile.save()
(Separately, please stop naming your ForeignKeys as ending in "_id"; they're not IDs, they are the actual related objects.)

How to assign UserProfile with WishList without using a default user

I have an app that contains a model UserProfile()
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
city = models.CharField(max_length=50, default='')
phone = models.IntegerField(default='0')
image = models.ImageField(upload_to='profile_image', blank=True)
def __str__(self):
return self.user.username
connecting to a default user(User). I wanted to connect my user with a wishlist model
class WishList(models.Model):
toy_name_wish = models.ForeignKey(Toy, on_delete=models.CASCADE)
user_wish = models.ForeignKey(UserProfile, on_delete=models.CASCADE)
def __str__(self):
return self.user_wish
And using generic view with def post(self, request): I created simple logic for a toy that will be shown in admin part as a user's wish item
class DetailToyView(TemplateView):
template_name = 'app/detail_toy.html'
#other defs
def post(self, request, toy_id):
toy = get_object_or_404(Toy, pk=toy_id)
user_profile = UserProfile()
wishlist = WishList()
try:
selected_toy = get_object_or_404(Toy, pk=toy_id)
except(KeyError, Toy.DoesNotExist):
return render(request, 'app/detail_toy.html', {'toy': toy})
else:
user_profile.user = self.request.user
user = user_profile.user
wishlist.toy_name_wish = toy
wishlist.user_wish = user
wishlist.save()
return HttpResponseRedirect(reverse('app:detail-category-toy', args=(toy.id,)))
If it's important here's my urls.py file
from django.urls import path
from django.conf.urls import url
from . import views
from django.contrib.auth import views as auth_views
app_name = 'app'
urlpatterns = [
path('', views.index, name='index'), # INDEX
path('personal-page/', views.personal_page, name='personal-page'),
# SIGN_IN, SIGN_OUT AND SIGN_UP
path('sign-in/', auth_views.login,
{'template_name': 'app/sign_in.html'},
name='sign-in'),
path('sign-out/', auth_views.logout,
{'next_page': '/'},
name='sign-out'),
path('sign-up/', views.sign_up, name='sign-up'),
# DETAIL_PAGES
#url(r'^book-detail/(?P<book>[0-9]+)/$', views.detail_book, name='book'),
url(r'^detail_category_toy/(?P<category_id>[0-9]+)/$', views.detail_category_toy, name='detail-category-toy'),
url(r'^detail-toy/(?P<toy_id>[0-9]+)/$', views.DetailToyView.as_view(), name='toy')]
So here is the problem when I click on the button I'm getting an error
ValueError at /detail-toy/2/
Cannot assign "<SimpleLazyObject: <User: admin>>": "WishList.user_wish" must be a "UserProfile" instance.
This means I cannot use user.username
So how do I get UserProfile instance instead of the basic User model?
P.S: Sorry for some stupid-called variables
Well, your immediate problem is that you are setting a User to the WishList object rather than a UserProfile. The line before the save should be:
wishlist.user_wish = user_profile
But really there are a lot of odd things going on here. A user can only have a single UserProfile, which sounds right, but in this view you always create a new one; if that user already has a profile, this will cause an error. And your WishList model is not really a list, but a single relationship between a profile and a toy.
What you actually need here is a many-to-many relationship between UserProfile and Toy, which is the wishlist:
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
city = models.CharField(max_length=50, default='')
phone = models.IntegerField(default='0')
image = models.ImageField(upload_to='profile_image', blank=True)
wishlist = models.ManyToManyField('Toy')
(and you don't need the WishList model at all)
And in your view, use get_or_create to either get the existing profile or create a new one:
def post(self, request, toy_id):
toy = get_object_or_404(Toy, pk=toy_id)
user_profile = get_or_create(UserProfile, user=request.user)
user_profile.wishlist.add(toy)
return HttpResponseRedirect(reverse('app:detail-category-toy', args=(toy.id,)))

How to display twitter feeds based on users in django & tweepy?

I want to show twitter data based on twitter username in my
template (Tweepy) but I don't know how to send data from my models into my views.
The content of models.py is:
<pre>
from django.db import models
from django.conf import settings
User = settings.AUTH_USER_MODEL
# Create your models here.
class Feed(models.Model):
owner = models.ForeignKey(User, on_delete=models.CASCADE)
feed = models.CharField(max_length=211, blank=True, null=True)
twitter = models.CharField(max_length=211, blank=True, null=True) # this is the twitter username which the user can enter and be sent to the views to api.get_user(twitter)
def __str__(self):
return self.feed
</pre>
The content of views.py is:
<pre>
from django.shortcuts import render
from django.views.generic import TemplateView
from .tweet import *
from .models import Feed
def feed(request):
api = tweepyapi(request)
user = api.get_user(twitter) # I want this portion to be dynamic.
findfriends = user.friends()
return render(request, 'feeds/feeds.html', {
'user': user,
'findfriends': findfriends
})
</pre>
let's say you have Profile model related to User model via one-to-one relation
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="profile")
twitter_username = models.CharField(max_length=40, blank=True)
def get_absolute_url(self):
context = {
'id':self.id,
}
return reverse("viewprofile", kwargs=context)
and in your template, we provide a link to user's profile as
{% for user in user_list %}
{{ user.get_full_name }}
{% endfor %}
now assuming you are passing id of user in get_absolute_url, your url will look like
url(r'^(?P<id>[0-9]+)/$', views.feed, name="viewprofile")
and then in your view
def feed(request,id):
profile = get_object_or_404(UserProfile,user__id=id )
api = tweepyapi(request)
user = api.get_user(profile.twitter_username)
findfriends = user.friends()
return render(request, 'feeds/feeds.html', {
'user': user,
'findfriends': findfriends
})

Link an user to his profile page

How do I link the logged in user to his profile page?
{% if user.is_authenticated %}
Profile
Here are the involved parts:
views.py
#login_required
def profile(request, profile_id):
if profile_id == "0":
if request.user.is_authenticated:
userProfile = UserProfile.objects.get(pk=profile_id)
else:
userProfile = UserProfile.objects.get(pk=profile_id)
return render_to_response('blog/profile.html', {'userProfile':userProfile}, RequestContext(request))
urls.py
url(r'^profile/(?P<profile_id>\d+)/$', views.profile),
models.py
class UserProfile(models.Model):
user = models.OneToOneField(User)
bio = models.TextField(max_length=500, blank = True, default=('keine Angabe'), null=True)
image = models.FileField(null=True, blank=True)
def __unicode__(self):
return self.user.username
In you template you are trying to use url tag with named urls even though you haven't passed name keyword argument to url function in your urlpatterns.
In your urls function pass name argument, like this:
url(r'^profile/(?P<profile_id>\d+)/$', views.profile, name='profile'),
make sure you namespaced the app as 'blog' in your root url conf.
In your template to access current user's profile id by request context's user object. Like this:
{% if user.is_authenticated %}
Profile