How do I add an index to Django's User model - python

My Django project always sorts Users by their first name, and I'd like to create an index on the field, but since it's a Django-defined model, I can't add it into the built-in code. First, does Django already have an index on the first name field? If not, can I add an index somehow? I know I could subclass the User model and handle all of the intricacies with that, but is there another way?

Based on the source code https://github.com/django/django/blob/master/django/contrib/auth/models.py#L320 , There's no db_index on the first name field.
You should Extending Django’s default User to have your own db_index
https://docs.djangoproject.com/en/1.8/topics/auth/customizing/#extending-django-s-default-user

Related

How to add a conditional field in a Django model?

Basically, what I want is a field to be available if a condition is met, so something like this:
class ConditionalModel(models.Model):
product = models.ForeignKey(product, on_delete=models.CASCADE)
if category == "laptop":
cpu_model = models.CharField(max_length=200)
so if I were to go to the Django admin page and create an instance of the model and then choose "laptop" as the product from the drop-down list of existing "products", a new field would be available. I couldn't find anything about this in the documentation, so I'm wondering whether it's even possible.
What you are asking for is not "technically" possible. A model relates a database object, and under traditional SQL rules, this isn't possible. You could instead make that field optional, and then customize the admin page's functionality.
Another potential option, though I do not have much experience with it, would be to use a NoSQL database in the case where you don't want to store NULL values in your db.
I do not think it is possible because models defines databases tables so the column has to be present.
You can use the keyword blank=True to allow an object without this field.
Maybe you can customize the admin interface to hide the field in some cases.
You can't do that in models.
You can hide it in admin panel or you can make separate model for laptop.
Or you can make field blank=True
Making a field optional is not possible but you can use a generalized model called Product and two or more specialized ones called for example : ElectronicProduct that contains the field cpu_model and NonElectronicProduct, the two specialized models have to contain a OneToOneField to the Product model to ensure inheritance.

Django - Custom Form Field Example

I have a project in which I need to add a custom form field to a form (or formset) in which depending on the choice in the custom field selected, an integer in a database field is changed.
I can't seem to find any examples or prior questions which imply how to modify a database field via a custom field. I suspect it is done by overwriting the save() function in a ModelForm but cannot work out how.
Any advice on solving this problem would be greatly appreciated.
An Example:
My class has an integer field which is the field that needs updating.
class Employee(Model):
years = models.IntegerField()
However this field cannot be updated as it is, instead what is needed is a ChoiceField (I think) with different options that, depending on the selection, changes the field with a +1, -1, or reset to zero.
As previously mentioned this is where I imagine some work with the save() function needs to be done but am unsure.
As a side note in case this affects what can be done, eventually this ModelForm will need to be used in a formset so I can edit multiple objects on one page.

How can I reuse django form for searching?

I am programming an application in django, and I have a model where I defined some fields that are necessary to be filled. This way, when te user doesn't fill one of these fields, Django authomatically indicates to the user to fill it to create the specific object defined by the model.
But myquestion comes here: I want to reuse the same form to search objects defined by that model. And in this case, all the fields that before were necessary, now are OPTIONAL. But, as I have already defined the model so that the fields are necessary, django doesn´t let me define those fields as optional.
Is there any way to reuse that form where the fields are necessary, but making them OPTIONAL? Or I must create another different model or form in html? I know that creating another form manually in the html code the problem is solver, but I have curiosity to know if it can be reused.
Thank you so much!
You can programmatically change properties of a field within a form using its fields dictionary. So you could create a new form class that is derived from your current form class and in its __init__ set the required property of the fields you desired to be optional to be False like so:
self.fields['title'].required = False

Create a dynamic admin site

I want to create a dynamic admin site, that based on if the field is blank or not will show that field. So I have a model that has a set number of fields, but for each individual entry will not contain all of the fields in my model and I want to exclude based on if that field is blank.
I have a unique bridge identifier, that correlates to each bridge, and then all of the various different variables that describe the bridge.
I have it set up now that the user will go to a url with the unique bridgekey and then this will create an entry of that bridge. So (as i am testing on my local machine) it would be like localhost/home/brkey and that code in my views.py that corresponds to that url is
However, not every bridge is the same and I have a lot more variables that I would like to include in my model but for now I am just testing on two : prestressed_concrete_deck and reinforced_concrete_coated_bars. What I want is to dynamically create the admin site to not display the prestressed_concrete_deck variable if that field is blank. So instead of displaying all of the variables on the admin site, I want to only display those variables if that bridge has that part, and to not display anything if the field is blank.
Another possible solution to the problem would be to get that unique identifier over to my admins.py. I cant figure out either how to get that individual key over as then I could query in the admins.py. If i knew how to access the bridgekey, I could just query in my admins.py dynamically. So how would I access the brkey for that entry in my admins.py (Something like BridgeModel.brkey ?)
I have tried several different things in my admin.py and have tried the comments suggestion of overwriting the get_fields() method in my admin class, but I am probably syntactically wrong and I am kind of confused what the object it takes exactly is. Is that the actual entry? Or is that the individual field?
Just override the get_fields method in your ModelAdmin class.
You can check the obj is passed as function argument so you can check which fields are empty. The function needs to return a tuple so, you would check if field1 is None and then return (field1, field2, field3) or (field2, field3) depending on the value of field1.
I was using Django 1.6 which did not support overriding the get_fields method. Updated to 1.7 and this method worked perfectly.

Filter a User list using a UserProfile field in Django Admin

I'm trying to filter the User list in Django using a UserProfile Field... I need to implement a queue system where new users are put in a queue until an Admin approves them.
I simply added a is_in_queue boolean field to my UserProfile model... However, when displaying the user list in my Admin area, I realized that you can't filter the list using a Model's foreign key field (in this case, a field of UserProfile)
Apparently, list_display items can be callables but list_filter can't, so I can list IF a user is in the queue without a problem, but the admin would have to scroll through the whole user list to spot which ones are in the queue which makes no sense... Filtering only users that are in the queue (using userprofile.in_queue) would be much more practical...
Finally, I thought about adding a custom view to my admin area that would list only the user in the queue, but that custom view does not show up on the Admin area Index page, and putting together a whole new AdminSite only for a new filtering option seems a bit over the top...
So basically to sum it up: Can I filter my User list based on a
UserProfile field? If not, can I add a custom view that's accessible
from the front page without having to create a completely new
AdminSite only for that?
Django 1.3 fixed that - list_filter now allows to span relations:
https://docs.djangoproject.com/en/1.3/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_filter
You may want to take a look in to using a custom manager for the admin_objects of your model.
class UserAdminManager(models.AdminManager):
"""
Custom manager for the User model.
"""
def get_query_set(self):
"""
Overwrites the get_query_set to only return Users in the queue.
"""
return super(UserAdminManager, self).get_query_set().filter(userprofile__queue=True)
By overwriting the get_query_set method you can filter the results. Then just assign this to the admin_objects property of your User model.
admin_objects = UserAdminManager()
Some of the property names in my example may be wrong, as I don't know your model setup, but hopefully you get the idea.
You can research this further by checking out the django docs and searching for "custom managers".
It sounds to me like the quickest and easiest option is to add a new admin view to your application, specifically for your custom user model. See the Django admin docs for details, though it sounds like you know how to use Admin already.
Once the admin page is specific to your model, all your custom fields will no longer be foreign keys. This would make filtering easy.

Categories