I am creating a Web2py application for a retail store. The requirement is that I use the auth_user table and there are two types of Users - 'Normal' and 'Admin'.
My question is how do I add a field to the auth_user table which has the constraint that it can contain only two values? What I would want ideally is that when the login page is rendered using SQLLFORM, the field for User_type should appear as a dropdown containing the two values (i.e, Normal and Admin).
I have googled it and could not find anything satisfactory. Any help would be awesome. :)
Thanks in advance. :)
After defining the auth object but before calling auth.define_tables, do something like:
auth.settings.extra_fields['auth_user'] = [
Field('role', requires=IS_IN_SET(['Normal', 'Admin']))]
For more details, see the documentation on customizing Auth and the IS_IN_SET validator.
Related
Django comes with default tables like AuthGroup, AuthGroupPermissions , AuthPermission, AuthUser, AuthUserGroups, AuthUserUserPermissions, DjangoAdminLog, DjangoContentType, DjangoSession and DjangoSite. What is the significance of each table?
I know that these tables comes from the apps included in the settings.py file, but I really dont understand the need to use some of the following tables above, such as Permissions and Groups. Where will I exactly use these tables?
The significance of the tables:
AuthGroup: Contains your groups, just id and name
AuthPermission: Contains the permissions of your project id, codename and a ForeignKey to the ContentType (Model) they belong to
AuthGroupPermissions: Table to keep the many to many relation between AuthGroup and AuthPermission (which permissions each group has)
AuthUser: Your users - username is the primary key
AuthUserGroups: Table to keep the many to many relation between AuthGroup and
AuthUser (which users belong to each group)
AuthUserPermissions: Table to keep the many to many relation between AuthUser and AuthPermission (which permissions each user has)
DjangoAdminLog: Records actions (insert/delete/update) your admin users do
DjangoContentType: Contains the content types of your project -- a content type is actually a Model in general - more info here https://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/
DjangoSession: Contains session information (session key, data and when it expires), more info here https://docs.djangoproject.com/en/dev/topics/http/sessions/
DjangoSite: Contains the sites your application can be used on - more information here: https://docs.djangoproject.com/en/dev/ref/contrib/sites/
Now, you answer your other question, you don't actually need to use these tables yourself. You will use the django ORM to create Users, Groups, Permissions etc and these tables will be updated through the ORM.
I'm currently using Django 1.5.1 and using a custom user as described in the official documentation. I realized everything is stored under one table, the auth_user one.
My question is, why is it better to have everything in one big table, instead of having 2 tables like it used to be prior to 1.5 by using a user_profile table for all additional data? It seems smarter the way it used to be, in case we want to add 20 new fields for information about the user, it is weird to have everything in auth_user.
In my case, for now I have class MyUser(AbstractUser) with 2 additional fields gender and date_of_birth, so it's all good with this, but now I would like to have many other information (text fields) like "favorite movies", "favorite books", "hobbies", "5 things I could not live without", etc. etc., to have way more information about my user. So I was just wondering if I should put that under MyUser class, or should I define a UserProfile one? And why?
Thanks!
When you have it all in one table, then database access is faster. With the old way you had to join on the auxiliary table to get all the information of the user.
Usually when you see a One-to-One relation, it would be better just to merge them in one table.
But the new custom User model solves also another problem, which is what atributes a User should have? What attributes are essential for your application? Is an email required? Should the email be also the username with which a user logs in?
You couldn't do these stuff before this feature was introduced.
Regarding your question about where to put additional user information like "hobbies" and such, it really depends on how often you will query/need this attributes. Are they gonna be only on the user's profile page? Well then you could have them in a seperate table and there wouldn't be much problem or performance hit. Otherwise prefer to store them on the same table as the User.
I have an existing web2py application. Now I need to create a new registration form using a db Table that includes a Field that requires a Row from a different Table.
This should be similar to what you commonly see with Country Fields in registration forms, except I want people to be able to add values to the 'Country' Table if the value doesn't already exist.
Making a small improvement to the previous response:
# create auth
auth = Auth(db)
# create the country table
db.define_table('country',
Field('name'),
Field('desc'),
format = '%(name)s')
# say you want to add it to auth_user table (not yet created)
auth.settings.extra_fields['auth_user']=[Field('country','reference country')]
# ask auth to make the auth tables, including auth_user
auth.define_tables()
JMax is right. We are more responsive on the web2py mailing list.
You can use a one to many relation (cf. the book):
db.define_table('country',
Field('name'),
Field('desc'))
db.define_table('user',
Field('name'),
Field('origin'), db.country))
Btw, you can ask your questions on the web2py Googlegroup where Massimo will probably be more reactive
I'm working on a project,
this project must have many users, each user can create for examples many support tickets and he could see them and edit them, but he is not allowed to access any other ticket, which not belong to him
so for example :
def edit_ticket():
record = db.e_ticket(request.args(0),active=True) or redirect(URL('error'))
form=crud.update(db.e_ticket,record,next='view_ticket/[id]')
return dict(form=form)
in this way with (request.args(0)) the user can edit every ticket in the system just to change the id to any other id and it will work
edit_ticket/[id]
so i changed the request.args(0) with auth.user_id, it was a great solution as i thought! but when we've many users so only the 1st and 2ed user could edit this thier tickets the next users cannot do that and receive an error when they do this "edit_Ticket/[id]"
Error the document doesn't exist
what should i do to prevent users from bypassing their privilege
Regards
it shouldn't be:
db.e_ticket(request.args(0),user_id==auth.user_id,active==True)
but
db.e_ticket(request.args(0),user_id=auth.user_id,active=True) -
because here we're passing function arguments and not query conditions
web2py has buildin user access control. please reference the web2py book:
users should login to edit their ticket, so you can use #auth.requires_login() to decorate edit_ticket(). In edit_ticket() you can check whether the user_id has the ticket_id first.
Maybe look into using authorization and CRUD (and generally how to set permissions on particular database records).
Note, you can't replace request.args(0) with auth.user_id. request.args(0) is referring to the id of the e_ticket record, not the user id. If the e_ticket table includes a field referencing the user id (e.g., e_ticket.user_id), then you could add user_id=auth.user_id as a condition.
next='view_ticket/[id]'
You should use the URL() function to create URLs -- URL(f='view_ticket',args=[id]). Also, what is [id] supposed to be -- I don't see any reference to id in the code?
This are my first steps with django so please take no offense if this seems trivial.
I have a very huge table mynames (~ 1 000 000 entrys) and I want to make this table editable in the django admin site. I hooked things up like described in the official django book: I have a model, and I registered it by admin.site.register(mymodel). I can see the "table" on my admin site and I can click on it to see the first page full of names. That is nice so far. As soon as I click on the "show next page button" at the bottom of the page, the query seams to take forever.
Where could the problem be?
Update:
I added an index to the relevant column and now it is fast. I thought by doing
name = models.CharField(max_length=100, db_index=True, unique=True)
in the model definition there would be an index for this column. But there was none. Only unique index. Is this the way it should be or do I miss something?
It would be easier to see what the problem is if you pasted your full model class. Is there a specified ordering on the table? If so, you need to create a corresponding index to make pagination on that field fast. Is the list_display attribute set on the ModelAdmin class for the model? By default, django should order the rows based on the primary key so you should not need an additional index. Also check if you have overridden the __unicode__ method for the model in a way that causes additional database lookups when showing the entity in django admins table?