I need to create custom users in my app.
In the example given in the doc
class CustomUser(models.Model):
user = models.OneToOneField(User)
#custom fields
a user must exists before creating a CustomUser.
What I want to do is to create automatically a User when I create a CustomUser.
In the CustomUser admin (only visible by the superuser), I'd like to have only the custom fields and a few fields from the User model, as well as some form to allow the superuser to change the password for existing instance.
Anybody could help?
The first part of your question is easy, you can use a signal:
def create_custom_user(sender, instance, created, **kwargs):
if created:
custom_user, created = CustomUser.objects.get_or_create(user=instance)
post_save.connect(create_custom_user, sender=User)
As for the second part, theres already a change password form in the admin. To filter out the displayed fields you can create a CustomUserAdmin and register it together with the model. It's pretty self explaining in the django docs.
django docs: list_display
Related
Is there a way to send an e-mail to a user when their account is activated through the Django admin application? I can do it independently of the Django admin application but I want the admin to be signed in before they activate a user. Is there a way to achieve this without customizing the Django admin application code? Thanks in advance.
Well, you can override the ModelForm and add the email sending logic in clean method. Also use that modelform in the Admin class. For example:
class UserForm(forms.ModelForm):
manual_activation = forms.BooleanField() # a flag which determines if the user should be manually activated
class Meta:
model = User
fields = '__all__'
def clean(self):
manual_activation = self.cleaned_data.pop('manual_activation', False)
if manual_activation:
# send_email logics
return self.cleaned_data
class UserAdmin(admin.ModelAdmin):
form = UserForm
What will happen is that, in the User admin page, if you click on an user it will show an extra field in the form, named manual_activation. If you check and save the form, then in clean method, you can catch the value of manual_activation and based on that send email.
I have a custom user setup like this:
class CustomUser(AbstractUser):
pass
class Employee(CustomUser):
user = models.OneToOneField(settings.AUTH_USER_MODEL)
# other fields
In settings.py, I then add the following key:
AUTH_USER_MODEL = 'myapp.CustomUser'
I want to identify who logged in redirect them to appropriate views or urls.
In my account activation view, after the logging them in I redirect them to their appropriate page like this
if hasattr(user, 'employee'):
return redirect('edit_employee', slug=user.employee.slug)
else:
return redirect('index')
But this doesn't feel that right as I need to use this in other places like showing a different profile page link in the templates.
How do I better identify the regular user and employee in views and templates?
AFAIK you should not store different types of users in different tables. It will make your life pretty hard when defining relationships between other models and your users model.
My suggested approach would be having different profile models for different types of users and using a generic FK or some sort of other similar approaches to find out the user type and get their profile.
class CustomUser(AbstractUser):
USER_TYPE_EMPLOYEE = 'employee'
USER_TYPES = (
(USER_TYPE_EMPLOYEE, _('Employee')),
)
user_type = models.CharField(max_length=max(map(len, map(operator.itemgetter(0), CustomUser.USER_TYPES))), choices=CustomUser.USER_TPYES)
#property
def profile_model(self):
return {
USER_TYPE_EMPLOYEE: EmployeeProfile
}[self.user_type]
#property
def profile(self):
return self.profile_model.objects.get_or_create(user_id=self.pk)
class EmployeeProfile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, related_name='employee_profile')
The idea of extending the User Model to create an Employee Model doesn't seem good to me. Instead of this, you can use Django Group Model and add the user to the employee group. In this way, you can easily check if a user belongs to Employee group or not.
Additionally, you can also use django permissions here.
Assign your custom permissions to the employee group and restrict other users to view employee pages.
I'm migrating something from an old PHP/apache server to Django. I'm a bit stumped with the 'ModelForm'.
As far as I understand, a "Model" is the abstraction for persistent elements in my website/server - specifically this is something stored physically, say in a database, and defines the fields (read columns) in the DB.
I started moving the authentication part of the site, and discovered models, and specifically the User model (I made an empty User inheriting AbstractUser just in case I will ever need to extend things). Now I want to create a simple two field form, to authenticate login.
The form:
Username (which is a field of User, by default)
Password (Which is not).
Even the 'Username' needs a redefinition in the model form. So my questions:
What is the advantage of the model form (over just a form)? - seems like you're redefining fields anyway, and obviously sometimes adding fields on top of the model.
Specifically for authentication, I probably need to store my salted hash associated with the user somehow, compare my password using that and retrieve the user object. This is something I find very hard to find in the Django docs - they just have too much written on authentication, and not one full code example. Do I put this in the "validate" method of form, retrieving there an object and storing it in a session or something?
If there is a deeper relation between a model form and the associated model, I would like to know as well.
Simple django forms and modelforms have quite differences.
class ArticleForm(ModelForm):
class Meta:
model = Article
fields = ['pub_date', 'headline', 'content', 'reporter']
The above example illustrates that you don't have to write any form field in here. The model form will itself create a form which is based on the attributes provided in the model ('Article' in this example).
If you create a simple django form then it would be something like:
class ArticleForm(forms.Form):
some_field = forms.CharField(some_attrs)
...
The django User model provides you everything you need for authentication. When you want to create users just import django.contrib.auth.models.User and use create method to create objects. Then when you want to authenticate a user use authenticate method.
from django.contrib.auth import authenticate, login
def user_login(request):
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(request, username=username, password=password)
# after authentication login the user or set cookies or modify the session or some other action can be taken
return HttpResponse("Some response or use render for html page")
username and password will be coming from your post request.
If you want to extend default Django user model you can use django user model as onetoonefield in your extended model.
class AppUser(models.Model):
user = models.OneToOneField(User)
... # other custom fields
So my question is what should I look for creating a page which will allow user to add some information after the registration. I took a look at Django Profiles, but it requires lower version of Python (2.7), if I'm not mistaken.
Another thing is I need to create two types of users - I'm thinking of maybe #permission to implement it, but another point is that I want to include something like checkbox while registration, and if user chooses one type of user, he will be allowed to see default account page for this type of user which he should fill up.
I'm running Django 1.10.5 and Python 3.6.0.
Thanks in advance.
If you want to add custom fields to your user object take a look at custom user model django implementation. Then, for updating user object you can just use generic update view, it will look something like this:
from django.contrib.auth import get_user_model
class UserUpdateView(UpdateView):
model = get_user_model()
fields = ['field1', 'field2', 'field3']
template_name = "core/user_edit.html"
I am working on a Django Project, where one model (lets say Document) has the following field:
#In models.py
class Document (models.Model):
choice = (('Yes','Yes'), ('No','No'))
authorized = models.CharField (max_length=3, choices=choice, default='No')
Now, as a normal user creates a Document object, the authorized field is no. However, the superior needs to authorize the same before it is actually approved. Now, is there a permission system in django where one user can create an object but not authorize, whereas some other user - who has the permission - can authorize? If not, is the only way to do it is to create a custom field in user model and check it every time?
First of all, why you need to store possible values in CharField and not in BooleanField? I think you should consider changing to BooleanField.
You can do that by providing custom ModelAmin class in admin.py:
from django.contrib import admin
from .models import Document
#admin.register(Document)
class DocumentModelAdmin(admin.ModelAdmin):
def get_form(self, request, obj=None, **kwargs):
if not request.user.is_superuser:
self.exclude = ['authorized']
return super(DocumentModelAdmin, self).get_form(request, obj, **kwargs)
So now on admin page of Document if it is not a superuser, user won't see authorized field. You can change that code for checking if it should be specific user, or has some permissions, or if user belongs to some Group and etc.
UPDATE
If you want it to be in general views, you can just pass different forms to users, depend on their roles|permissions|groups(i don't know how your so called senior is different from rest of the users). So the answer would be: create two forms, then pass on of them in template based on your request.user attributes.
Django has awesome auth system. I couldn't understand you scenario.
But you could try something like this below
By default every Model object comes with three Permission object like (add_document, change_document and delete_document in your case).
If you want some custom permission you can add it in model Meta class like this:
You can add these permission to User object or Group object.
models.py
class Document (models.Model):
######
class Meta:
permissions = (("Can see document dashbaord", "see_document" ),)
and run python manage.py migrate to create new Permission object with codename as "see_document".
You can implement permissions in request handled by view like this:
view.py
from django.contrib.auth.mixins import PermissionRequiredMixin, permission_required
# For function based view
#pemission_required('document.see_document')
def someview(request):
######
pass
# For class based views
class SomeView(PermissionRequiredMixin, BaseView):
permission_required = 'document.see_document'
This could redirect any user with out the permssion to permission denied page. For more go through this https://docs.djangoproject.com/en/1.10/topics/auth/