In my django app I have a custom user model with a username field called my_username. Recently I made this field non unique (actually it is now unique_together with another field). This makes django to emit the following warning in manage.py:
(auth.W004) 'MyUser.my_username' is named as the 'USERNAME_FIELD', but it is not unique.
HINT: Ensure that your authentication backend(s) can handle non-unique usernames.
Is there a way to prevent this warning for displaying? I only found ways to disable all warnings, but I want to disable only that specific one.
Since Django 1.7, there is a setting to silence certain warnings. If you are using Django 1.7 or later, you can add the error code to the SILENCED_SYSTEM_CHECKS setting:
# settings.py
SILENCED_SYSTEM_CHECKS = ["auth.W004"]
source: https://docs.djangoproject.com/en/dev/ref/settings/#silenced-system-checks
Related
I'm starting a project using an existing db. The models generated from inspectdb have
(...null=True, blank=True)
in various fields. The documentation mentions that the blank argument is related to django forms. I'm making a web service project, using django rest framework and the django ORM. Absolutely no view component (autogenerated forms, html templates, etc) of the MVC.
Does that mean it's safe to remove blank=True from my models?
Without blank=True your application will fail validation when trying to serialize data with blank fields. Django rest framework ModelSerializer enforces any kind of validation that is on the model fields. It works similarly to Django ModelForms.
If you're not using ModelSerializers and try to save a blank value against a field without blank=True your save method will throw an exception instead.
TL;DR: if you remove blank=True your DRF serializer will fail validation against empty fields.
Take a look at this question on how validation works in DRF.
Hope this helps!
Probably not.
Whatever your service is, you probably want to validate data. And Django's validation relies on that blank=True. It's not just for forms and templates. From the documentation:
blank is validation-related.
Django Rest Framework will use the blank attribute on a model field in serializer validation. When blank is False, which is the default value, the ModelSerializer will raise a ValidationError if a value is not set for this field in a POST request.
Basically, if you remove blank=True from a field and try to create a record with no value for that field, you will get a 400 response from your server.
Nothing will break, just this request will fail to create a resource. In my book I'd call that safe. It really just comes down to whether you want the field to be required or not. But since you have null=True, it seems reasonable to have blank=True.
I have a UUID field in Django 1.6 imported from django-uuidfield v0.4.0. I can't change Django versions.
id = uuidfield.UIIDField()
And all is fine, except when attempting to view the model in the Admin, when this error is displayed:
expected a character buffer object
The problem seems to be this line:
return mark_safe(force_text(value).translate(_js_escapes))
from site-packages/django/utils/functional.py
I have tried to exclude this field from the Admin view by excluding it specifically
exclude=('id',)
and by including a different field explicitly, hoping it would only process that field and not the ID field (as the docs seem to indicate).
include = ('email',)
But the error persists. It seems as if the Admin site is examining the fields anyway, ignoring any settings in the Admin setup. I have also set 'editable=False' in the model definition with no effect for the id field.
I don't need to manipulate or edit this field in any way from the admin screen, just hide it so it does not crash the admin.
I'm not sure where you are importing that from, but Django has included its own UUIDField since version 1.7. You should certainly be using that instead.
I am starting with Django App schema design and my schema has UserProfile, UserFavourites and UserComments models .
After doing a bit research i found out that we can user django's own User model or we can create own user model which will extend from AbstractUser
Platform = Django 1.8.5
I have found many similar questions but now that i have newest version of Django framework has anything changed ?
Also need to know pros and cons of each approach
In a new project, strongly consider starting out with a custom User model.
The reason is that if you want to change your User model later, then there is a clear way to do that (migrations). However, switching from a auth-User to a custom User when you already have ForeignKey relations (etc) to the auth-User is a major pain (see below). Considering that it is very easy to just start out with your own model at the start of a project (maybe just copy the auth model), there is very little reason not to.
The docs say this about how hard it is to change AUTH_USER_MODEL later:
Warning
Changing AUTH_USER_MODEL has a big effect on your database structure.
It changes the tables that are available, and it will affect the
construction of foreign keys and many-to-many relationships. If you
intend to set AUTH_USER_MODEL, you should set it before creating any
migrations or running manage.py migrate for the first time.
Changing this setting after you have tables created is not supported
by makemigrations and will result in you having to manually fix your
schema, port your data from the old user table, and possibly manually
reapply some migrations.
Warning
Due to limitations of Django’s dynamic dependency feature for
swappable models, you must ensure that the model referenced by
AUTH_USER_MODEL is created in the first migration of its app (usually
called 0001_initial); otherwise, you will have dependency issues.
In addition, you may run into a CircularDependencyError when running
your migrations as Django won’t be able to automatically break the
dependency loop due to the dynamic dependency. If you see this error,
you should break the loop by moving the models depended on by your
User model into a second migration (you can try making two normal
models that have a ForeignKey to each other and seeing how
makemigrations resolves that circular dependency if you want to see
how it’s usually done)
In other words, if you choose not to use AUTH_USER_MODEL at the start of your project, it's almost impossible to change later.
There is a ticket #24370 for adding custom user model and AUTH_USER_MODEL setting to the default project template, and to recommend doing this in the documentation. This ticket is just waiting for someone to implement it.
Pulled from Django's documentation
If you wish to store information related to User, you can use a one-to-one relationship to a model containing the fields for additional information. This one-to-one model is often called a profile model, as it might store non-auth related information about a site user
So just add your extra user fields to UserProfile Model. Make a one-to-one relationship with each of your desired model
I am trying to add two additional profile fields and have the native authentication work like normal.
I am trying to fallow the documentation here
and the SO here
In my settings file
#settings.py
AUTH_USER_MODEL = 'users.User'
in my users.user model
#users/models.py
from django.contrib.auth.models import AbstractUser
from django.db import models
class User(AbstractUser):
foo = models.CharField(max_length=32, default='Blue')
bar = models.CharField(max_length=32, default='Blue')
print "user.user"
i have created 3 superusers non can log into admin. i have tried syncing the DB after adding a user. i have tried restating the dev server between adding a user.
the only time i see the output of print "user.user" is when i run the createsuperuser command.
i think i cant log in because the user is not really being created. it runs my User class and then skips actually creating the user. but i am kinda new to this so i could be way off and way out of my league.
why cant i log in and how do i add the two fields?
Have you read the warning in Django's documentation?
Changing AUTH_USER_MODEL has a big effect on your database structure. It changes the tables that are available, and it will affect the construction of foreign keys and many-to-many relationships. If you intend to set AUTH_USER_MODEL, you should set it before running manage.py syncdb for the first time.
If you have an existing project and you want to migrate to using a custom User model, you may need to look into using a migration tool like South to ease the transition.
Given this warning, are you working on a fresh database, or are you migrating using South? If you have an existing database and made these changes, then simply running syncdb will most likely no be sufficient.
If this is a development server without any important data, I would recreate your database, and then run ./manage.py syncdb. If you are using a SQLite database, then you can simply copy it to somewhere else (if you would like to keep the data), and run syncdb again to create a new database.
Here is the relevant documentation.
It would also be helpful to know exactly what error you are receiving. Do you attempt to login and admin tells you that your user/pass combination is not correct, or is there an actual error thrown? Your question doesn't quite make this clear.
With Django 1.5 and the introduction of custom user models the AUTH_PROFILE_MODULE became deprecated. In my existing Django application I use the User model and I also have a Profile model with a foreign key to the User and store other stuff about the user in the profile. Currently using AUTH_PROFILE_MODULE and this is set to 'app.profile'.
So obviously, my code tends to do lots of user.get_profile() and this now needs to go away.
Now, I could create a new custom user model (by just having my profile model extend User) but then in all other places where I currently have a foreign key to a user will need to be changed also... so this would be a large migration in my live service.
Is there any way - and with no model migration - and only by creating/overriding the get_profile() function with something like my_user.userprofile_set.all()[0]) somewhere?
Anyone out there that has gone down this path and can share ideas or experiences?
If I where to do this service again now - would obviously not go this way but with a semi-large live production system I am open for short-cuts :-)
Using a profile model with a relation to the built-in User is still a totally legitimate construct for storing additional user information (and recommended in many cases). The AUTH_PROFILE_MODULE and get_profile() stuff that is now deprecated just ended up being unnecessary, given that built-in Django 1-to-1 syntax works cleanly and elegantly here.
The transition from the old usage is actually easy if you're already using a OneToOneField to User on your profile model, which is how the profile module was recommended to be set up before get_profile was deprecated.
class UserProfile(models.Model):
user = OneToOneField(User, related_name="profile")
# add profile fields here, e.g.,
nickname = CharField(...)
# usage: no get_profile() needed. Just standard 1-to-1 reverse syntax!
nickname = request.user.profile.nickname
See here if you're not familiar with the syntactic magic for OneToOneField's that makes this possible. It ends up being a simple search and replace of get_profile() for profile or whatever your related_name is (auto related name in the above case would be user_profile). Standard django reverse 1-1 syntax is actually nicer than get_profile()!
Change a ForeignKey to a OneToOneField
However, I realize this doesn't answer your question entirely. You indicate that you used a ForeignKey to User in your profile module rather than a OneToOne, which is fine, but the syntax isn't as simple if you leave it as a ForeignKey, as you note in your follow up comment.
Assuming you were using your ForeignKey in practice as an unique foreign key (essentially a 1-to-1), given that in the DB a OneToOneField is just a ForeignKey field with a unique=True constraint, you should be able to change the ForeignKey field to a OneToOneField in your code without actually having to make a significant database migration or incurring any data loss.
Dealing with South migration
If you're using South for migrations, the code change from the previous section may confuse South into deleting the old field and creating a new one if you do a schemamigration --auto, so you may need to manually edit the migration to do things right. One approach would be to create the schemamigration and then blank out the forwards and backwards methods so it doesn't actually try to do anything, but so it still freezes the model properly as a OneToOneField going forward. Then, if you want to do things perfectly, you should add the unique constraint to the corresponding database foreign key column as well. You can either do this manually with SQL, or via South (by either editing the migration methods manually, or by setting unique=True on the ForeignKey and creating a first South migration before you switch it to a OneToOneField and do a second migration and blank out the forwards/backwards methods).