I am using 0.97-pre-SVN-unknown release of Django.
I have a model for which I have not given any primary_key. Django, consequently, automatically provides an AutoField that is called "id". Everything's fine with that. But now, I have to change the "verbose_name" of that AutoField to something other than "id". I cannot override the "id" field the usual way, because that would require dropping/resetting the entire model and its data (which is strictly not an option). I cannot find another way around it. Does what I want even possible to achieve? If you may suggest any alternatives that would get me away with what I want without having to drop the model/table, I'd be happy.
Hmm... and what about explicitly write id field in the model definition? Like this for example:
class Entry(models.Model):
id = models.AutoField(verbose_name="custom name")
# and other fields...
It doesn't require any underlying database changes.
Look into the command-line options for manage.py; there's a command to dump all of the model data to JSON, and another command to load it back in from JSON. You can export all of your model data, add your new field to the model, then import your data back in. Just make sure that you set the db_column option to 'id' so you don't break your existing data.
Edit: Specifically, you want the commands dumpdata and loaddata.
Related
Is it possible get a queryset from a table in the app database that is NOT a model in the app?
If I have a table that is not a model named "cartable", conceptually, I want to do this:
myqueryset = cartable.objects.all()
Is there a relatively easy way to do this? Thanks!
If you want to access an existing table in your database that is not managed by your application, you can still create a class for it, and tell django to ignore it for migrations.
Just create a model and add the fields you need to access and then add a meta class to tell django to leave it alone.
class MyModel(model.Model):
class Meta:
managed = False
you can read about that at https://docs.djangoproject.com/en/1.9/ref/models/options/#managed
To do so you would need to create a class (not a model), with methods that use raw SQL. You should see more details here on how to do so: https://docs.djangoproject.com/en/1.9/topics/db/sql/#executing-custom-sql-directly
Please note that you will have to manually create the object with the right properties afterwards.
If you wanted to use Django ORM without the models, I don't think it is possible. You could however create a model that matches your db in a separate app and never create migrations for it to ensure you don't accidentally modify the DB.
Short answer is, "not really". Django QuerySet deals with model instances, so everything in QuerySet API is tied into models. Everything expects to return model instances, uses model fields etc.
That said, you should be able to create a model for an existing table. You will need to add db_table to the Meta, so Django knows where the table lives. If you have some indexing, you will need to make sure Django's idea of indexes is the same as the one in the database. indexed=True on fields and unique_together in Meta should help a lot with that.
I have to add dynamic fields at run time in my django application,but I don't know the proper way how to add new fields at run time.
I want to add the code which will generate the dynamic field and will update database too. I am using postgresql database. please help if anyone can.
My "model.py" is simply like this:
class Student(models.Model):
name=models.CharField(max_length=100)
school=models.CharField(max_length=100)
created_at=models.DateField(auto_now_add=True)
is_active=models.BooleanField(default=False)
def __str__(self):
return self.name
Django is not made for dynamic models, as relational databases are not. A model change at runtime will create a ton of problems.
You have to simulate it, by...
clever use of related models
storing values in a large field, e.g. JSON as text
having a generic model that stores the data as key, value; e.g. a table with PK, a FK, key, value as columns.
You should try the first option and only if that does not work out try the other two.
Can I add additional fields to ModelSerializer subclass?
By saying 'additional field', I mean some fields don't belong any models in database, which any effort that try to map those fields to exist model fields will fail. The reason I need to include those fields is for design purpose. I need to those fields' value to do the validation and creating a new instance eventually.
I know there is a kwarg in ModelSerialzer called 'context'. By putting all the additional information into 'context', it will work. However, I want to know is that possible to create additional fields?
I have tried adding 'write_only=True', which doesn't work. The only left option is to override default restore_object method to create the instance with my will.
Any other ideas?
As you have not posted any code I can only give you a generic answer, but if I understand you correctly, you wish to add a custom field to a ModelSerializer thats not part of your model...
In DSF you can do this very esaily (read here):
In this case you just want a simple read-only field, so instead just use:
custom_field = Field(source='get_whatever')
In terms if validation after that please read the DRF guide here
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).
I've got a django form that contains a join via a foreign key. This is a foreign key to a very large table. On the form, to prevent loading up a massive select that tends to crash browsers, I've got a jQuery autocomplete, which on each keystroke sends off the entered text. This text is then searched in the table and suitable results are returned to be displayed. The id is then passed to a hidden CharField when one is selected. This hidden CharField is the widget for the ForeignKey relation. When I try to save the form, I get an error that I need to be passing a model instance for the related model, which is fair enough. I can't work out how to do this however. I can take that id and do a model.objects.get(pk=id_from_form), but if I replace the POST data with the result of this, I still get an error as I'm just passing the __unicode__ method of the model. I'm sure there's something I'm missing, but I can't see what it is.
Thanks.
Instead of using a CharField to store the id, try using a ModelChoiceField with the widget set as a HiddenInput. The field definition in your form would look something like:
mymodel = forms.ModelChoiceField(widget=forms.HiddenInput, queryset=MyModel.objects.all())