Django: add index to meta field - django

I have the following model:
from model_utils.models import TimeStampedModel
class MyModel(TimeStampedModel):
....
name = models.CharField(max_length=100)
....
This model is based on Django Utils (https://django-model-utils.readthedocs.org/en/latest/models.html#timestampedmodel) which adds created and modified fields to my model.
What I need know is way to add a db_index to the modified field of my model. But I can't modify the TimeStampedModel file because it is part of an external dependency.
Do you know any easy solution for this kind of issue?
Thank you.

Yes you can using model Meta.
if you don't need to inherit meta from the TimeStampedModel just use this:
class Meta:
...
otherwise you need to explicitly tell django to look into the parent's meta first like this:
class Meta(TimeStampedModel.Meta):
this might be a hackish solution but maybe you can try using index_together to make django create an index for your model:
like this:
class Meta(TimeStampedModel.Meta):
index_together = [
["modified",],
]
try it out and tell me if it worked
EDIT:
Another solution coming from: How to override the default value of a Model Field from an Abstract Base Class:
try adding this to your MyModel class
MyModel._meta.get_field('modified').db_index = True

Related

Django model reference when using AbstractBaseUser model

I 'm following a tutorial of how to use AbstractBaseUser model in Django project. Now I would like to go one step further by creating other models for example address_book and product.
When using defaulter user model, we put like this:
class User(models.Model):
....
class AddressBook(models.Model):
....
class Product(models.Model):
....
Now when I use like
class MyUser(AbstractBaseUser):
Which reference should I use in the AddressBook and Product class? (The user in the Address book is a foreign key from Class MyUser).
class AddressBook(AbstractBaseUser) and class Product(AbstractBaseUser) or
class AddressBook(models.Model) and class Product (models.model)?
Thanks for your help in advance!
In Python if you define a class like that
class ClassName(SuperClassName):
...
You are extending one or more existing classes. This is inheritance, not a reference.
If you want a reference you might want something like this:
class AddressBook(models.Model):
user = models.ForeignKey('MyUser', on_delete=models.CASCADE)
...
For more detailed information I recommend looking at this page in the documentation.

How to define django-imagekit ImageSpecFields in parent/mixin class?

I'm using django-imagekit to provide thumbnail versions of uploaded images on my Django models.
I would like to define various thumbnail ImageSpecFields in a mixin that my models can then inherit. However, each model currently has a different name for the ImageField on which its ImageSpecFields would be based.
I've tried this:
from django.db import models
from imagekit.models import ImageSpecField
from imagekit.processors import ResizeToFit
class ThumbnailModelMixin(models.Model):
IMAGE_SPEC_SOURCE_FIELD = None
list_thumbnail = ImageSpecField(
source=IMAGE_SPEC_SOURCE_FIELD,
processors=[ResizeToFit((80, 160)],
format="JPEG",
options={"quality": 80}
)
class Meta:
abstract = True
class Book(ThumbnailModelMixin):
IMAGE_SPEC_SOURCE_FIELD = "cover"
cover = models.ImageField(upload_to="books/")
class Event(ThumbnailModelMixin):
IMAGE_SPEC_SOURCE_FIELD = "ticket"
ticket = models.ImageField(upload_to="events/")
But this fails on page load with:
AttributeError: 'Book' object has no attribute 'list_thumbnail'
Is there a way to get inheritance like this to work?
There are at least two other solutions:
Don't use a mixin/parent, and include the ImageSpecFields on each child class - a lot of duplicate code.
Change the Book.cover and Event.ticket fields to have the same name, like image and use "image" for the ImageSpecField source parameter.
The latter sounds best, but I'm still curious as to whether there's a way to get the inheritance working?

'UserManager' object has no attribute 'raw_query'

nonrel(Mongodb) with tastypie.I have created one resource class which return selected auth_user from the database.Because of some reasons I did change _id field type from ObjectId to Int64.I used raw_query() for accessing desired auth_user but it doesn't seems to work.Can anyone suggest me what should I do to make raw_query() work for UserModel.
Here is my tastypie resource:
class UserResource(ModelResource):
class Meta:
queryset=User.objects.raw_query({'_id':5})
resource_name="user"
fields=["username","first_name","last_name"]
include_resource_uri=False
allowed_methods=["get"]
output:
'UserManager' object has no attribute 'raw_query'
I myself workaround to this problem and for the sake of others help I am answering my own question.Hope this will help someone.
This solution is to create a proxy model.By declaring proxy models we can do opertions on parent model and even can modify manager.
proxy model:
class UserClass(User):
objects = MongoDBManager()
class Meta:
proxy=True
Resource:
class UserResource(ModelResource):
class Meta:
queryset=UserClass.objects.raw_query({'_id':5})
resource_name="user"
fields=["username","first_name","last_name"]
include_resource_uri=False
allowed_methods=["get"]
This is not related to Tastypie at all. Are you sure you need a raw query, or is the above just an example?
By looking at the docs you should be able to do the following:
from django_mongodb_engine.contrib import MongoDBManager
class User(models.Model):
mongo_manager = MongoDBManager()
Then you should be able to use it as you do above, i.e:
queryset=User.mongo_manager.raw_query({'_id':5})

Dynamically add to the model's Meta class?

Normally, you specify a table name for your model by putting in the model class:
class MyModel(models.Model):
class Meta:
db_table = 'desired_tablename'
I want to add the table names for all my models dynamically at the end of models.py.
Can this be done in Django? If yes, how?
Yes, this can be done simply like this:
MyModel._meta.db_table = 'desired_tablename'

modeling extra table information with django's contenttypes

I've just started using Django's contenttypes framework (and it's pretty awesome). I have an Area object that has many specialised Block objects - I've modeled it as below.
class Area(models.Model):
...
class SomeBlock(models.Model):
...
class AreaBlock(models.Model):
area = models.ForeignKey(Area)
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
block_object = generic.GenericForeignKey('content_type', 'object_id')
This works very well. Now I want to register these specialised blocks in their own table along with extra 'global' information about it.
class BlockRegistrar(models.Model):
...
My problem is joining SomeBlock to it's global information in the BlockRegistrar model. A foreignkey in the block table would be obvious, but it wouldn't ever change and I can't figure out how to use django's ContentType table to do these joins.
Any help?
So AreaBlock.block_object is a GenericForeignKey to one of several possible SomeXXBlock models?
Do you mean every SomeXXBlock record has a corresponding BlockRegistrar record?
The easiest way to do that would be with model inheritance:
class BlockRegistrar(models.Model):
# 'global' fields common to all SomeXXBlock models
...
class SomeBlock(BlockRegistrar):
...
class SomeOtherBlock(BlockRegistrar):
...
Behind the scenes Django automatically creates a OneToOneField linking the SomeXXBlock instance to it's corresponding BlockRegistrar. In Django this is called 'multi-table inheritance'. From your question it sounds like this may be what you want.
If you never need to access a BlockRegistrar object directly, but just want the global fields to be available on all the SomeXXBlock 'child' models then you could use an Abstract base model:
class BlockRegistrar(models.Model):
# 'global' fields common to all SomeXXBlock models
...
class Meta:
abstract = True
class SomeBlock(BlockRegistrar):
...
class SomeOtherBlock(BlockRegistrar):
...
In this case the BlockRegistrar model does not exist as a table in the db and there is no magic OneToOneField added to the SomeXXBlock models.