Django. get_profile() don't work - python

I want to get information from current user in my forms.py
My Model:
class Users(models.Model):
first_name = models.CharField('First name', max_length=50)
....
user = models.OneToOneField(User, editable=False)
My view:
#login_required
def editAccount(request):
if request.method == 'POST':
form = EditAccountForm(request.user, request.POST)
if form.is_valid():
form.save()
My Form:
class EditAccountForm(forms.ModelForm):
class Meta:
model = Users
def __init__(self, user, *args, **kwargs):
self.user = user.get_profile()
I put in my settings.py AUTH_PROFILE_MODULE = "user.Users", I have this error: Deprecation Warning: The use of AUTH_PROFILE_MODULE to define user profiles has been deprecated. self.user = user.get_profile()
I'm new on django I don't see my mistake.
Thanks a lot

There is no error in your code. What you see is just a deprecation warning.
Starting Django 1.5, AUTH_PROFILE_MODULE has been deprecated in favour of custom User models.
Your code should still work though, but ideally you should read up on custom User model and start using it.

The AUTH_PROFILE_MODULE setting, and the django.contrib.auth.models.User.get_profile() was depreciated in Django 1.5 See AUTH_PROFILE_MODULE
For your code try this:
models.y
class Users(models.Model):
user = OneToOneField(User, related_name="profile")
forms.py
class EditAccountForm(forms.ModelForm):
class Meta:
model = Users
def __init__(self, user, *args, **kwargs):
self.user = user.profile
Here's the related question with answers

Another thing that you could do is simple call the model that created the user and
request for the information. IE
Your created user profile.
class User(models.Model):
username = models.OneToOneField(User, editable=False)
first_name = models.CharField("Last name", max_length=50)
last_name = models.CharField("First Name", max_length=50)
email = models.EmailField(blank=True)
def __str__(self):
return "%s" % self.username
Then in your view you could do something like
class UserProfileView(View):
def get(self, request):
self.user = request.user
#from here you can call your user model requesting for the user information.
self.userdetails = Users.objects.get(username=self.user)
if(self.userdetails):
#user exists
#you can pass this to the templates and perform actions on using loops
for details in self.userdetails:
print details.username
print details.first_name
print details.last_name
#.....

Related

How to override model form to create a user in Django

I am trying to create a new user from the modelform by calling the CustomerUserManager in managers.py
class CustomUserCreationForm(UserCreationForm):
def __init__(self, *args, **kwargs):
super(CustomUserCreationForm,self).__init__(*args, **kwargs)
try:
if args[0]["email"]:
self.email= args[0]["email"]
self.password= args[0]["password1"]
except:
pass
class Meta:
model = CustomUser
fields = "__all__"
def save(self, **kwargs):
return CustomUserManager.create_user(self,email=self.email,password=self.password,name="hic")
The managers.py is
class CustomUserManager(BaseUserManager):
def create_user(self, email, password, name,**extra_fields):
...
user = self.model(email=email,name=name, stripe_customer_id=customer.id ,**extra_fields)
user.set_password(password)
user.save()
return user
Obviously the self.model does not exist, so how can I correctly create that user from the modelform? If I import the model, I get circular error import.
here is my model.py
class CustomUser(AbstractUser):
username = None
email = models.EmailField(_('email address'), unique=True)
name = models.CharField(verbose_name=_("first name"), max_length=50)
stripe_customer_id = models.CharField(max_length=120)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['name']
objects = CustomUserManager()
I'm not sure why you would want a save function in your form, rather than in your view using the model's save() function after your form data has validated...
That said, if you do want a create_user function in your manager, you would call it like
from django.contrib.auth import get_user_model
get_user_model().objects.create_user(...)
This should ensure the model is present to be referred to.

How to give access for a model object to a specific user in Django

I am doing an online classroom project in Django where I created a model named create_course which is accessible by teachers. Now I am trying to design this as the teacher who creates a class only he can see this after login another teacher shouldn't see his classes and how to add students into that particular class I created
the course model
class course(models.Model):
course_name = models.CharField(max_length=200)
course_id = models.CharField(max_length=10)
course_sec = models.IntegerField()
classroom_id = models.CharField(max_length=50,unique=True)
views.py
def teacher_view(request, *args, **kwargs):
form = add_course(request.POST or None)
context = {}
if form.is_valid():
form.save()
return HttpResponse("Class Created Sucessfully")
context['add_courses'] = form
return render(request, 'teacherview.html', context)
forms.py
from django import forms
from .models import course
class add_course(forms.ModelForm):
class Meta:
model = course
fields = ('course_name', 'course_id', 'course_sec', 'classroom_id')
Add one more field in course model that establish relationship with User model. Hence you can get the details about the teacher who has created course.
from django.contrib.auth.models import User
class course(models.Model):
course_name = models.CharField(max_length=200)
course_id = models.CharField(max_length=10)
course_sec = models.IntegerField()
classroom_id = models.CharField(max_length=50,unique=True)
created_by = models.ForeignKey(User, on_delete=models.CASCADE)
In your view function, you can check whether logged in user is same as the created of the requested course.
def teacher_view(request, *args, **kwargs):
# since this is course specific view, you will be passing an identiier or pk of the course as an argument to this function.
course_obj = Course.objects.get(id="identifier")
if request.user == course_obj.created_by:
# logged in user is same as the creator of the course
else:
# redirect
I would prefer creating permissions and having those in specific models. You can give it a try with that too. Let me know, if it doesn't work.

How to obtain a user instance in django application

I'm trying to obtain a user instance for the profile page in django app but I'm finding some difficulties implementing that functionality. I have the following blocks of code:
models.py
class Profile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, primary_key=True, on_delete=models.CASCADE, default="")
image = models.ImageField(upload_to="images/user_profile_pics/", default="images/default_profile_pics/default.jpg")
firstname = models.CharField(max_length=50)
lastname = models.CharField(max_length=50)
def __str__(self):
return f'{self.lastname} profile'
serializers.py
class user_profile_serializer(serializers.ModelSerializer):
class Meta:
model = Profile
fields = '__all__'
views.py
class user_profile(generics.GenericAPIView):
serializer_class = user_profile_serializer
def get(self, request, *args, **kwargs):
user = self.get_serializer(request.user).data
if request.user.is_authenticated:
return Response(user, status=status.HTTP_200_OK)
else:
pass
urls.py
urlpatterns = [
path('profile/', user_profile.as_view(), name="user-profile"),
]
When ever I assess the profile url, I get an error message 'AnonymousUser' object has no attribute 'data' I have tried a couple of approaches but none worked. Please, how do I obtain a specific user from the database?
request.user is AnonymousUser when the user is not logged in. In that case that object does not have data attribute. Hence the error you get. One thing you can do is check request.user.is_authenticated and if the user is not authenticated, return some other value / or None. And try logging in before trying to access the user.data value.

Django: Do not allow users to see pages when login details do not match with custom models details

I have custom model where login details have been stored:
class UserRegistration(models.Model):
# Auto updated when data is inserted
created_at = models.DateTimeField(auto_now_add=True, auto_now=False)
# Auto updated when data is altered
updated_at = models.DateTimeField(auto_now_add=False, auto_now=True)
username = models.CharField(max_length=255, null=True)
password = models.CharField(max_length=255, null=True)
first_name = models.CharField(max_length=255, null=True)
last_name = models.CharField(max_length=255, null=True)
def __str__(self):
return self.first_name
urls.py is
url(r'^login/$', view.login_page, name='login_page'),
views.py is
def login_page(request):
if request.method == 'GET':
return render(request, "login_page.html")
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
print username, password
credentials_matches = False # considering credentials are wrong
all_users = UserRegistration.objects.all()
for user in all_users:
if user.username == username and user.password == password:
credentials_matches = True
break
if credentials_matches:
return HttpResponse('success')
# return redirect("http://127.0.0.1:8000/lmtech")
else:
return HttpResponse('fail')
I have other views that I do not wish to show to user if they have not logged in. I though about #login_required() but in this case, user details are in custom model. How do I solve this problem?
You must not make a custom user model like this. Writing your own authentication system is always insecure.
You should use the standard built-in auth framework - you can substitute your own user model but it must inherit from AbstractBaseUser, see the docs. However there doesn't seem to be much reason to do this as you don't add any custom functionality.
On your custom model, you want the first name, last, name, username and password, in User model from django you only have the email more which is optional. So what you can do is to créate a User with the django's model and then use a relationship to have the two other attributes you want.
Here is an example
class User(models.Model):
username = models.CharField()
password
...
class UserMore(models.Model):
user = models.OneToOneField(User)
created_at = ...
updated_at = ...
def __str__(self):
return self.user.username
In this case you then can use the #login_required() of django.
Personnaly, it's how I do.
But if you really want to keep your custom model without the User model of Django, maybe you can keep the user in a session that you initiate in your login view and then in your logout you delete it. In this way you can easily check if the request.session['username'] is defined or not.

Key error while using django crispy forms for login

I was trying to create a login form in django using crispy forms. During login authentication I have two fields: email_id and password. but in browser it only showing password field, and have following error:
Django version is 1.7
WARNING:root:Could not resolve form field 'email_id'.
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/crispy_forms/utils.py", line 74, in render_field
field_instance = form.fields[field]
KeyError: u'email_id'
The snapshot of the webpage being rendered is :
The model of the User for which I am trying to login is : model.py
class User(models.Model):
user_id = models.AutoField(primary_key=True)
title_id = models.ForeignKey('Title')
first_name = models.CharField(max_length=100)
middle_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
username = models.CharField(max_length=100, unique=True, default='')
password = models.CharField(max_length=100) # will be changed according to hash used
mobile_number = models.CharField(max_length=10)
alternate_number = models.CharField(max_length=10)
email_id = models.EmailField()
date_of_birth = models.DateField()
profession_id = models.ForeignKey('Profession')
house_no = models.CharField(max_length=100)
city_id = models.ForeignKey('City')
country_id = models.ForeignKey('Country')
state_id = models.ForeignKey('State')
locality_id = models.ForeignKey('Locality')
The class for login in the file view.py is:
class LoginView(generic.FormView):
form_class = LoginForm
success_url = reverse_lazy('profile')
template_name = 'login.html'
#model = User
def form_valid(self, form):
email_id = form.cleaned_data['email_id']
password = form.cleaned_data['password']
user = authenticate(email_id=email_id, password=password)
if user is not None and user.is_active:
login(self.request, user)
return super(LoginView, self).form_valid(form)
else:
return self.form_invalid(form)
The class for login form in forms.py is:
class LoginForm(AuthenticationForm):
def __init__(self, *args, **kwargs):
super(LoginForm, self).__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.layout = Layout(
'email_id',
'password',
ButtonHolder(
Submit('login', 'Login', css_class= 'btn-primary')
)
)
From what I can see (I am taking an educated guess, as you have not included your imports anywhere), you're using django.contrib.auth.forms.AuthenticationForm as the parent class for your LoginForm class, which is being used in LoginView.
The only two fields on the AuthenticationForm class are username and password, but you are trying to access an email_id field in your Layout object in LoginForm.__init__. This will not work, because there is no field named email_id to access.
The password field happens to show up on your page because there is a password field on AuthenticationForm, but if you're wanting to add email_id then you will need to either:
add email_id as a form Field on your LoginForm class, or
create a ModelForm using your User model, or
read this guide on how to specify a custom user model, and the steps necessary to integrate with django's auth app (I think this is what you want)
I am not sure whether you are trying to create a custom user model or not, but since you seem to be using the django.contrib.auth.authenticate function in your view (again, an educated guess, as there are no imports) then it seems that you're not following the correct pattern.

Categories