In working with the Django user model I've noticed model managers include a using=self._db parameter when acting on a database. If I'm only using a single database, is this necessary? What does using=self._db do other than specify the database. Is this specified as a fail-safe in the event another database is added?
Managers use that parameter to define on which database the underlying queryset the manager uses should operate on. This is simply there to optionally override it in case you have e.g. multiple databases and you want your manger/queryset to operate on a specific one.
Related
I am planning to use a same user model for two different users with some additional fields in one model. Is it possible to do this in Django? If it is possible, how can I do it?
You have two options :
Firstly
You create a new Model (call it ExtendedUser) and you put the extra fields in that model.
You then set your ExtendedUser model to inherit from your MainUser model. This will create two tables with a one to one link between them.
The advantage of this is that your ExtendedUser model will inherit any methods defined in your original MainUser model, and you only need add methods to the ExtendedUser model if you absolutely have to. You can also write functions which can deal with both the MainUser and ExtendedUser models easily, since they are all instances of the MainUser model. One of the benefits of using inhertiance is if you write a query on the ExtendedUser model fetching all fields, it well fetch the MainUser fields too.
A Second (worse) option :
Have a single extended model with a flag on it which says whether to use the extra fields. This can be made to work, but will make your queries more complex, and if you need the extra fields to be indexed, the indexes are likely to be a bit less efficient.
Note : having a second table with a relationship between the two is no bad thing in SQL - that is how data is normally managed. Having special optional fields for some types of users isn't great as mentioned.
I would like to create a custome admin view with fields with data that I fill manually, meaning that there's no database table behind.
In my admin.py I have this so far
class TestAdmin(admin.ModelAdmin):
pass
admin.site.register(Test, TestAdmin)
and in the models.py
class Test(models.Model):
test = models.BooleanField(
default=True
)
But with this I receive an error
django.db.utils.ProgrammingError: relation "..._test" does not exist
Django is looking up the table in the database but in my model I need only fields which data I fill manually
It seems that you don't really get what a Model and ModelAdmin are. A Model class is the representation of a database table, and a ModelAdmin is a component that provides administration features for this table and it's content. IOW, when you write that "there's no database table behind", you're missing the point somehow: you cannot have a ModelAdmin without a Model, and you cannot have a Model without a database table.
To make a long story short: you'll either have to
1/ use a model or
2/ write the whole view(s) and templates by yourself and plug them into the admin.
For the second solution, see this question (and it's answers), or just google for "django admin views without models" (there are a couple 3rd part apps that are supposed to help plugin custom views in the admin).
Now the first solution might - or not, depending on your exact needs - be as good as the second one, depending on who populates your s3bucket and how. Without a model, you'll have to query the bucket for a file listing each and every time someone accesses your custom admin view, which might get quite costly. If all the uploads to the s3 bucket are under your control, you can use a model to keep a local file listing "cache" and you'll only need to hit s3 when effectively downloading a file. This also gives you the opportunity to store metadata about those files - which can be used for searching / filtering - and eventually to link your s3 files to other models if needed. And of course this means you get your admin for free ;)
Actually even if you don't have control on those uploads, you may still want to use a model for the above reasons and have a background task (cron job or equivalent) that updatees your table from the s3 bucket contents (or - if s3 provides web hooks - have an API endpoint called by s3 on uploads that updates your table).
The way that django's ORM works is that all class members of a model class that is an instance of model.Field will map to a column in the database.
It is possible to have model properties that does not map to a database table. You could use a #property instead, for example.
class Test(models.Model):
#property
def test(self):
return get_aws_bucket_value(self.id)
#test.setter
def test(self, value):
set_aws_bucket_value(self.id, value)
You have to implement the aws getter/setter functions yourself.
You can use properties as read-only fields in the django admin class. Be careful about using it in the list view if your getter logic needs to fetch data from a remote server syncronously, since that would be a significant performance bottleneck.
If you want to be able to set values for a setter from the django admin, you would have to write a custom ModelForm for TestAdmin.
It is possible to wrangle Django into doing what you want here. But Django's models and admin are based around the ORM, which means using a relational database as persistant storage. If you don't want that, you can find yourself fighting against and overriding the framework more often than benefiting from Django's "batteries included". This project might be better solved with a less monolithic and less opinionated framework such as Flask instead of Django.
In django model query, i want to know the sequential execution of it. Consider a query Blog.objects.get(name='palm').
In this where the Blog is defined, is that same as class blog in models.py?
What is objects i can't find anything related to this in source files of django. If Blog is a class, then what is the type of objects?
I want a development side concept. Can any one please explain how django makes these possible?
Every non-abstract Django model class has an attribute objects attached to it (unless you of course explicitly remove it).
object is a Manager. It is an object that has a lot of methods to construct queries that are then send to the database to fetch/store data.
So you first access the objects manager of the Blog class, next you call .get(name='palm') on it. This means that Django will translate this into a query. This depends on the database system you use. For instance if it is MySQL it will look like:
SELECT name, some, other columns
FROM app_blog
WHERE name = 'palm'
The database will respond with zero, one or more rows, and Django will, in case no or more than one row is found, raise a DoesNotExists or MultipleObjectsReturned error. Otherwise it will load the data into a Blog object (by deserializing the columns into Python objects).
I am in the process of transitioning to the NDB, and I am using two model sets: one based in plain old google.appengine.ext.db and one based on new fancy google.appengine.ext.ndb.
I would like to use NDB-based models for read-only and retain the caching that's built into NDB, while being able to store changes using the old models (and signal the need to update caches to the NDB when needed).
How can I flush/clear cache for a specific model instance in the NDB while saving changes in the model based on old db?
I would recommend just disabling the cache for those model classes that you have in duplicate; better be safe than sorry. This is easily done by putting
_use_memcache = False
_use_cache = False
inside each ndb.Model subclass (i.e. before or after the property declarations). Docs for this are here: https://developers.google.com/appengine/docs/python/ndb/cache#policy_functions (look for the table towards the end).
If you really want to clear the cache only when you write an entity using a old db.Model subclass, instead of the above you can try the following (assume ent is a db.Model subclass instance):
ndbkey = ndb.Key.from_old_key(ent.key())
ndbkey.delete(use_datastore=False)
This deletes the key from memcache and from the context cache but does not delete it from the datastore. When you try to read it back using its NDB key (or even when it comes back as a query result), however, it will appear to be deleted until the current HTTP request handler finishes, and it will not use memcache for about 30 seconds.
Django's ORM supports querying from a specific database (when multiple are defined in your project) via the .using() function for filter-based operations.
e.g. MyModel.objects.filter(name='Bob').using('my_non_default_database')
How would you do the equivalent when creating new records, via the class MyModel() or shortcut like get_or_create()?
using is a method on the MyModel.objects manager, so you can do
MyModel.objects.using('my_non_default_database').get_or_create(name="Bob")
If you have a MyModel instance, you can use the using keyword to specify the database to save to. The django docs point out some gotchas.
my_model = MyModel(name="Bob")
my_model.save(using='my_non_default_database')
using is just part of the standard query chain. So, you can use it anywhere before the query is sent to the DB. get_or_create, unlike filter, is atomic: when you call it, it does it's thing immediately, so you just need to call using before that.
MyModel.objects.using('my_non_default_database').get_or_create(name='Bob')