I am not sure if i am titling this correctly, however i have a standard base.html file that includes block content from overridden allauth templates, mainly account/email.html, account/password_change.html, account/password_set.html and socialaccount/connections.html. each of these feed into base.html depending on tab selected. the tabs correspond to the default allauth views, accounts/email, accounts/password/change, accounts/password/set, and accounts/social/connections.
When i load base.html, I am able to grab the user profile information from a custom Profile model
#login_required
def base(request):
email = request.user
profile = Profile.objects.filter(my_user=email)
return render(request, 'base.html', {'profile': profile})
as long as i am on the base.html template view, the username displays in the upper right of the screen, and i have access to all profile information for use in the template. however, when i click onto an allauth default view, that still extends base.html, the username information in the header disappears and profile data is no longer available until i click back on the main base.html view.
Can someone help me with what i am missing on how to maintain the username in the upper right of the screen always in the base.html file (even as views change), as well as access to profile information across the different views?
Just in case this helps anyone else overriding AllAuth Views, was able to solve via:
class MyEmailView(EmailView):
def get_context_data(self, **kwargs):
email = self.request.user
profile_data = Profile.objects.filter(my_user=email)
context = super(MyEmailView, self).get_context_data(**kwargs)
context["profile_data"] = profile_data
print(context["profile_data"])
return context
urls.py
# override of email view to add user profile context data
path("accounts/email/", MyEmailView.as_view(), name="account_email"),
Related
This is my view
class UserRegistrationView(FormView):
template_name = "register/register_form.html"
form_class = None
extra_fields_form_page_slug = ""
email_template = "register/account_activation_email.html"
def get_form(self, form_class=None):
form = super().get_form(form_class)
add_extra_fields(
form.fields, form.helper.layout.fields, self.extra_fields_form_page_slug
)
return form
def get_extra_form(self):
return FormPage.objects.filter(slug=self.extra_fields_form_page_slug).first()
def form_valid(self, form):
user = form.save(commit=False)
user.is_active = False
user.save()
email = form.cleaned_data.get("email")
email_template = "register/account_activation_email.html"
send_confirmation_email(
self, "Activate Your Account", user, email, email_template
)
return render(self.request, "register/after_submission.html")
This is working fine (registration wise) but it's not from many other sides, because I have the registration form as a pop up window in the header, so it's available throughout the whole website, my problems are:
if the user had a successful registration they will be redirected to the specified template "after_submission" what I want is to stay on the same page and display a pop up with some message
if the user had an unsuccessful registration they will be redirected to the main template "register_form.html" with the errors displayed their, what I want is to stay on the same page and to display the error messages on the pop up form if the user opened it again
is this achievable using only Django?? or I must throw some JS in there, and if JS is the answer, can you give me a quick insight into how to do it?
You can redirect to the same page in your CBV :
from django.http import HttpResponseRedirect
return HttpResponseRedirect(self.request.path_info)
As stated in the comment your solution require Ajax and JS, you can however redirect to the same page but that will make a new request and refresh the whole page which might no be ideal for you.
There is a tutorial to work with Django and Ajax Ajax / Django Tutorial
So I have a my user profile view you can see as a logged in user. I wanted to add a second view so other logged in users can visit profile pages as well, but I'm not really sure I'm doing it the right way
urls.py
url(r'^accounts/profile/', main_views.uprofile, name='uprofile'), #the page you see as my profile
url(r'^profile/(?P<pk>\d+)/$', main_views.oprofile, name='oprofile'), # the page i use so other users can view the profile page
url(r'^accounts/update/(?P<pk>\d+)/', User_Profile_views.edit_user, name='edit_user'), #Custom update profile page
main_views.py
#login_required(login_url='/accounts/login/')
def uprofile (request):
context = locals()
template = 'profile.html'
return render (request, template, context)
def oprofile (request, pk):
user = User.objects.get(pk=pk)
context = locals()
template = 'profile.html'
return render (request, template, context)
From product point of view, you would want to keep same url for both uprofile and oprofile. One simple reason being, when I visit my profile and if I want to share it with someone else, I'd just copy-paste the url.
How to do that?
In your view, pass a flag that helps your template to render the right elements. For instance, if the user is same as the profile being visited, pass a flag, say editable, and use it to show edit buttons. And instead of two views, you can have single view.
Also, instead of id, people tend to remember their username/handle. So it's better to have username. However, make sure you have unique username for all users.
urls.py
url(r'^profile/(?P<username>[\w\-]+)/$', main_views.profile, name='profile'),
views.py
def profile (request, username):
# If no such user exists raise 404
try:
user = User.objects.get(username=username)
except:
raise Http404
# Flag that determines if we should show editable elements in template
editable = False
# Handling non authenticated user for obvious reasons
if request.user.is_authenticated() and request.user == user:
editable = True
context = locals()
template = 'profile.html'
return render (request, template, context)
I have successfully implemented a way to create users belonging to different groups with userena using a different form for each signup url, inheriting the userena signup form and overriding the save method to include the user to a group or another.
For instance in my /brands/ urls I have:
url(r'^signup/$',
'userena.views.signup',
{'template_name': 'userena/signup_form_brands.html', 'signup_form': SignupFormBrands}
),
and in that form I have:
from userena.forms import SignupForm
from django.contrib.auth.models import Group
class SignupFormBrands(SignupForm):
def save(self):
# First save the parent form and get the user.
new_user = super(SignupFormBrands, self).save()
new_user.groups.add(Group.objects.get(name='Brands'))
return new_user
So I got what I needed with the batteries included in userena. But now I would like to keep using the included profile editing / viewing capabilities of userena but with 2 different kinds of profiles. I would like to create 2 different profile models, one for my default users and one for the brands. Then I want userena to be able to edit the right kind of profile model according to the user belonging to a group or another. I'm not sure how this works and how I could do it.
Edit: userena uses profile = user.get_profile()to edit the profile so I'm going to try to assign a different profile object by editing this class.
you can override User.get_profile by following code:
original_get_profile = User.get_profile
def get_profile(self):
if getattr(settings, 'AUTH_PROFILE_MODULE', None) != 'profiles.Profile':
return original_get_profile(self)
if not hasattr(self, '_profile_cache'):
self._profile_cache = self.profile
self.profile.user = self
return self._profile_cache
User.get_profile = get_profile
Put it somewhere in models.py file with your profiles.
code copied from here: http://pastebin.com/MP6bY8H9
As we know, After we add a new user in django admin site, page is redirected to editing profile, not user list page like other models. How to implement this in a normal model? For example I defined a model called Image and wanted to edit the image after the image had been uploaded.
Put the following function into your admin class.
django/contrib/auth/admin.py:L139
def response_add(self, request, obj, post_url_continue='../%s/'):
"""
Determines the HttpResponse for the add_view stage. It mostly defers to
its superclass implementation but is customized because the User model
has a slightly different workflow.
"""
# We should allow further modification of the user just added i.e. the
# 'Save' button should behave like the 'Save and continue editing'
# button except in two scenarios:
# * The user has pressed the 'Save and add another' button
# * We are adding a user in a popup
if '_addanother' not in request.POST and '_popup' not in request.POST:
request.POST['_continue'] = 1
return super(UserAdmin, self).response_add(request, obj, post_url_continue)
I have a requirement where I have to register users first via email. So, I went with django-registraton and I managed to integrate tat module into my django project.
After a successful login, the page redirects to 'registration/profile.html'.
I need to get access to the user object which was used in the authentication.
I need this object to make changes to a model which holds custom profile information about my users. I have already defined this in my models.py
Here is the URL I am using to re-direct to my template..
url(r'^profile/$',direct_to_template,{'template':'registration/profile.html'}),
So my question is this... after login, the user has to be taken to a profile page that needs to be filled up.
Any thoughts on how I can achieve this?
I have set up something similar earlier. In my case I defined new users via the admin interface but the basic problem was the same. I needed to show certain page (ie. user settings) on first log in.
I ended up adding a flag (first_log_in, BooleanField) in the UserProfile model. I set up a check for it at the view function of my frontpage that handles the routing. Here's the crude idea.
views.py:
def get_user_profile(request):
# this creates user profile and attaches it to an user
# if one is not found already
try:
user_profile = request.user.get_profile()
except:
user_profile = UserProfile(user=request.user)
user_profile.save()
return user_profile
# route from your urls.py to this view function! rename if needed
def frontpage(request):
# just some auth stuff. it's probably nicer to handle this elsewhere
# (use decorator or some other solution :) )
if not request.user.is_authenticated():
return HttpResponseRedirect('/login/')
user_profile = get_user_profile(request)
if user_profile.first_log_in:
user_profile.first_log_in = False
user_profile.save()
return HttpResponseRedirect('/profile/')
return HttpResponseRedirect('/frontpage'')
models.py:
from django.db import models
class UserProfile(models.Model):
first_log_in = models.BooleanField(default=True, editable=False)
... # add the rest of your user settings here
It is important that you set AUTH_PROFILE_MODULE at your setting.py to point to the model. Ie.
AUTH_PROFILE_MODULE = 'your_app.UserProfile'
should work.
Take a look at this article for further reference about UserProfile. I hope that helps. :)