Recently I am doing a function that need to customize max length of User model. Now I know that I have learned how to solve my requirement.
When I type this code, I can extend max_length:
User._meta.get_field('username').max_length = 100
User._meta.get_field('email').max_length = 100
I still can't understand what meta is. When I try to read Django document about meta model, I just know that I should how to use meta. I need more explanation that let me really understand the inner meaning about meta.
Model Meta relative link:
https://docs.djangoproject.com/en/1.7/ref/models/options/
https://docs.djangoproject.com/en/1.7/topics/db/models/#meta-options
From docs:
Model metadata is “anything that’s not a field”, such as ordering options (ordering), database table name (db_table), or human-readable singular and plural names (verbose_name and verbose_name_plural). None are required, and adding class Meta to a model is completely optional.
Thus, Meta is just a container class responsible for holding metadata information attached to the model. It defines such things as available permissions, associated database table name, whether the model is abstract or not, singular and plural versions of the name etc.
For the available Meta options, you can take a look at here.
As for your question, I would definitely avoid changing max_length to some other value like that, as you know, max_length also creates a database constraint such as VARCHAR(64) which can't be automatically updated to a new value (100) by Django.
Thus, if you want to change max length, make sure you also update the size of the column in the corresponding table column in the database:
For MySQL:
ALTER TABLE auth_user MODIFY username VARCHAR(100);
For PostgreSQL:
ALTER TABLE auth_user ALTER COLUMN username TYPE VARCHAR(100);
Related
I have a model with a foreign key that references the username field of auth.User. The original field has a maximum length of 150. But Django generates a foreign key with a maximum length of 30.
In my app's models.py:
class Profile(models.Model):
user = models.ForeignKey('auth.User', to_field='username')
In django.contrib.auth.models:
username = models.CharField(
_('username'),
max_length=150,
Generated SQL:
CREATE TABLE "myapp_profile" (
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
"user_id" varchar(30) NOT NULL REFERENCES "auth_user" ("username")
);
This only happens when referencing auth.User.username. If I reference a long field in my own model, the foreign key is generated fine.
Why is that? How can I overcome it?
Using Django 1.11.4 and Python 3.6.2. I tried PostgreSQL and SQLite and the problem occurs on both.
CLARIFICATION:
From the answers so far I think my question was misunderstood. I am not looking for a way to have long usernames. My problem is that the stock User model that comes with Django has one max_length (150), but when your model refers to it, the foreign hey has a shorter max_length of 30. Therefore if a user is registered with a username of 31 characters, I will not be able to create child objects of that user, because the foreign key constraint will be violated. And I need this because I have a REST API whose URLs nest resources under uses, that are referred by username, not ID. For example: /users/<username>/profiles/...
UPDATE:
I think the reason for this behavior is the undocumented swappable property of the User model. It is designed to be replaceable by custom models. However, the configured model must have its data in the initial migration of the app that defines the model. The migrations code seems to generate references to the initial migration of swappable models. I am using the default User model, and its initial migration sets the username to 30 chars. Hence my username FKs are 30 chars long. I am able to work around this with a RunSQL migration to alter the FK data type to varchar(15), but I am in doubt if it's the right thing to do.
Is recommended use short identifier, varchar(30) is a long number, something like 999999999999999999999999999999, when Django make identifiers always use the same number. I don't think that you are going to use so much users if you reach that number you should create another type of identifier. Remember the long of the user_id field is the id of the username and not the string
You can use this hack described in this SO answer,
but be very careful!.
Or you can use this package.
However, I think that, as described in this discussion, the best way would be to create a custom User model and do whatever you want there.
Hope it helps!
You must use custom user model.Taken from django docs.
150 characters or fewer. Usernames may contain alphanumeric, _, #, +, . and - characters.
The max_length should be sufficient for many use cases. If you need a longer length, please use a custom user model. If you use MySQL with the utf8mb4 encoding (recommended for proper Unicode support), specify at most max_length=191 because MySQL can only create unique indexes with 191 characters in that case by default.
Well, I do my first steps with Django and Django REST framework. The problem I face is that all examples throughout the whole Internet are based on hard-coded models. But the whole concept of models frustrates me a little bit, because I'm used to deal with different data which comes from numerous sources (various relational databases and nosql - all that stuff). So, I do not want to stick to a particular model with a fixed number of predefined fields, but I want to specify them just at the moment when a user goes to a particular page of my app.
Let's say I have a table or a collection in one of my databases, which stores information about users - it has any kinds of fields (not just email, name and likewise - all those fields as in all those examples throughout the web). So when a user goes to /users/ I connect to my datebase, get my table, set my cursor and populate my resultant dictionary with all rows and all fields I need. And REST API does all the rest.
So, I need a "first-step" example wich starts from data, not from a model: you have a table "items" in your favorite database, when a user goes to /items/, he or she gets all data from that table. To make such simplistic api, you should do this and this... I need this kind of example.
I think the key is to use the models differently. If you use onetomany or foreignkey references in your model construction you can more dynamically link different types of data together, then access that from the parent object.
For example, for your user, you could create a basic user model and reference that in many other models such as interests, occupation, and have those models store very dynamic data.
When you have the root user model object, you can access it's foreign key objects by either iterating through the dictionary of fields returned by the object or accessing the foreign key references directly with model.reference_set.all()
There is something that is tripping me up with models, and I guess SQL tables in general.
Let us suppose you have these models:
class Manufacturer(models.Model):
name = models.CharField()
company_created = models.CharField()
class Car(models.Model):
manufacturer = models.ForeignKey(Manufacturer)
When you create an instance of Car like say, the following
civic = Car(manufacturer='honda')
A couple questions:
When you create an instance of Car, are you also creating an instance of Manufacturer as a by-product? Or does 'honda' need to exist as an instance already. If not, is there a way to make an instance of both, in say, one form.
Can I make calls on 'civic' for things pertaining to the manufacture? For example, could I get the 'company_created' data from the civic instance? If not, why bother having the relationship in the first place?
Thanks so much in advance. I would really appreciate a thorough answer so I can understand models and relationships fully. And yes, I have read the docs.
Firstly, the thing to remember is that these classes are representations of underlying database tables. A ForeignKey field in a Django model represents a one-to-many relationship in the database, with an _id field representing the ID of another table. Those tables are themselves independent, but are linked via the FK field (and the relevant index constraint, if the database supports them).
That said, in your Car model manufacturer is a required field (because you haven't defined it as null=True). So when you create a Car, you must point it at an already existing Manufacturer - and that manufacturer must have been saved already, so that Django can populate the underlying manufacturer_id field with the ID of the related object
Because Django is aware of the foreign key relationship between the two objects, you can use them when querying. In SQL this would be done via JOINs: Django gives you a special syntax to do queries across those joins, via double underscores. So, for example, if you wanted to get all the cars made by a manufacturer created in 1990 (assuming that's what you mean by the company_created field), you would do this:
Car.objects.filter(manufacturer__company_created='1990')
Django translates this into something like":
SELECT * from car JOIN manufacturer ON car.manufacturer_id=manufacturer.id WHERE manufacturer.company_created='1990';
If you already have your "civic" instance and just want to get access to the related data, this is pure Python object access: civic.manufacturer is the related Manufacturer object, so you can simply do civic.manufacturer.company_created to get the relevant data. Again, Django translates that into the database access, but from your point of view this is simple object composition.
Note that really all this is fully explained in the tutorial, with relationships between Poll and Choice which exactly match your Manufacturer and Car models.
Yes manufacturer need to exist as an instance already.
you can create car instance like this:
manuf= Manufacturer(name='honda',company_created='Benz')
manuf.save()
civic = Car(manufacturer=manuf)
you can get the company_created data from the civic instance by:
civic.manufacturer.company_created
When I create an object with ndb's method put it creates the key automatically of the type Key(kind, id) where id is a number. All over the documentation it shows that you can use a string for the key's id but I couldn't find out how to do this automatically when an object is created.
I have a User model and I was thinking to use the user's username (since its unique) as the key's id for faster retrieval. Is that even a good idea? Would I have any problems with the username since it's user submited (i'm validating the input)?
class UserModel(ndb.Model):
...
user_model_entity = UserModel(id='some_string', ...)
If these IDs are subject to change, this may be a bad idea. If it's your own system and you can react to potential changes, it is a fine idea, but you need make sure the IDs will be unique and relatively stable before deciding to use them.
You specify the id of the entity at the time of creation. When you define the model, you don't set an id attribute there. Thus, for example you have:
class User(ndb.Model):
# fields here
When you create the model, you have:
user = User(id='username', ...)
Since the username is unique and you validate your input, then you will not have any problems with this approach.
For more information about an ndb Model constructor, you can take a look at NDB Model Class - Constructor.
Hope this helps.
You can also supply integer ID (not necessarily a string) for your model entity.
class User(ndb.Model):
...
user = User(id=1234567890, ...)
user.put()
I am trying to figure out the best way to save a model that I've got using the django orm. I have a model/table, User. Additionally, I have a model/table called ContactInfo, where we store a foreign key to the User table.
I understand that common django orm practice would be to put the foreign key for the ContactInfo model into the User model, but at this point, we do not want to add anything to the already monolithic user table, so we put the foreign key into the ContactInfo model.
I understand that I can store the User model in the ContactInfo model, call save on ContactInfo, and it should save the User model, but what if I have a one-to-many relationship with users and their contact info? I would rather not have multiple instances of the user table within (1-many) instances of the contact info model/object.
If I can clear anything up, please let me know. At the current moment, the best idea I have is to store an instance of the ContactInfo list as user.contact_info, and override the save method for user user.save() to check for contact_info, and if it exists insert the user.id into each model and save. Unfortunately I just feel like this is a bit messy, but being new-er to django and python, I'm not sure what my options are.
Any help would be greatly appreciated, thanks!
I am not sure if I understand your question correctly. Django provides well support for 1-N relationship. If ContactInfo has a foreign key of User, by default, it's a 1-N mapping.
ContactInfo ---------> User
N 1
So, there is only one User record in your database, looks like this
Table User Table ContactInfo
---------------------------------------------
id user_name id user_id
1 someone 1 1
2 1
3 1
And you don't need to override save method. When you need to add a Contact,
contact = ContactInfo(user=target_user)
# other stuff
contact.save()
#or
target_user.contactinfo_set.create(...)#contactinfo_set is the related name of target_user
#Django maintains the foreign key things.
If you use methods above to insert a new ContactInfo record, then you do not need to iterate your contact_info list to insert user.id into the database.
I am not sure if you're meaning a custom User model or the standard model that ships with Django. If the latter, then Django provides a standard way of storing additional information, called user profiles, associated with each user. See this section in the documentation for details.