#django what method is used to represent a model field in admin - django

I am trying to subclass CharField with a custom unicode method. Basically, I want to be able to call my custom crypto method on the value that is returned by the default model field. I tried the following, but it seems that admin is getting the values some other way. It seems to me that this would be the most pythonic way to implement this, but perhaps I'm wrong.
def PasswordCharField(models.CharField):
def __unicode__(self):
return crypt(super(PasswordCharField,self).__unicode__())

I'm still not really sure why you're trying to encrypt a field on output - that doesn't seem very secure, the usual approach (taken by Django's own password fields) is to hash the data on entry and store that hashed version on the database.
However, if you want to go down this route, there's still no reason to use __unicode__ on a custom field subclass. There's nothing in the documentation that implies that this is what any part of Django - whether the admin or anything else - uses to get the value of a field. In fact, the admin uses exactly the same method to get the value of a field as anything else.
Custom field subclasses are fully described in the documentation, linked from the contents page. Without really understanding what you're trying to do it's hard to tell, but it could be that the to_python method is what you need. Bear in mind though that this will affect the value of the field for all uses in Django.

Related

Usage of latest() method with field types other than date field (Django)

I have just learned about the latest() method. I went to the django's documentation to find out more about it. In the docs it is written:
latest(field_name=None)
Returns the latest object in the table, by date, using the field_name provided as the date field.
However in the tutorial ,that I am following, this method is used together with field name for models.PositiveIntegerField() field(and the model does not specify get_latest_by). I have been trying to search for explanation and similar use of this method, where the field_name is different than date field.
I have found some information here where it is said that:
...it probably does work with other total-ordered types too, but not sure...
and
It does work with primary keys ...
Also I have found similar case here, where the latest() method is used with id field.
However still I did not find an answer whether it is ok to use this method with something other than date field? Is there any other method which is more appropriate for this kind of task?
Here's the source code for _earliest_or_latest, which powers the latest method. As you can see, it basically uses whatever field name you specify and tries its best to order your lookup by that field at the database level. It does this through the add_ordering method, which is documented in the source code here.
There's nothing fancy at all going on under the hood - Django is just passing an ORDER BY and letting the database try to sort things out. That's why you see inconsistent behavior between database environments, like how SQLite sorts nulls below non-nulls while MySQL and PostgreSQL do the reverse. Django isn't really ordering the queryset, it's the underlying database.
Things like dates, incremented IDs, etc. are easy for databases to order and therefore work well with latest. A UUIDField, on the other hand, probably wouldn't work so well.

Django validation best practice

I'm implementing a custom Django form which just contains an email address field.
As well as the usual email field type validation, I want to add some extra checks, such as whether this email address has already been used for this user etc.
What is the best practice way of doing this using class-based views (FormView, in this case, obviously) ?
Should I put the validation code:-
in the form_valid() method of the FormView or
in the clean_email() method of the form class
Option 2 seems the neatest to me, but if I go that way, I need to pass the user into the form (and pop it in the init method) so that the clean_email method can use to do database lookups which doesn't seem quite right either.
Use the latter approach since you know it would be neatest one.
Another benefit of going via this approach will be that you can identify which function your validation error occurred which might be helpful when you want to add more validations in future.
And then what other ways do you have to check if user is already present in the system.
You have to add the logic in view then.

Django - Custom backwards relation

An Setting belongs to an Office. Each time a Setting is updated, I make a new entry in the database, passing the old Setting to active=False and the new Setting to active=true. So each office has only one active setting at a time (i'm doing this because I wan't to keep track of old settings).
Now what I need is a way to access this setting via the Office object.
At the moment I am accessing it with the backwards relation office.setting_set.
I'm using Django-Rest-Framework so I need a field that is serializable.
In my serializer, I call: office.setting_set. In regular django I could probably do office.setting_set.filter(active=True) but I can't do so in a serializer...
The ideal would be a custom model field that I would call something like:
office.active_setting
Any idea how I can achieve this?
You can use model methods for this. The method would likely be something similar to the following:
def active_setting(self):
return self.setting_set.get(active=True)

What do I use instead of ForiegnKey relationship for multi-db relation

I need to provide my users a list of choices from a model which is stored in a separate legacy database. Foreign keys aren't supported in django multi-db setups. The ideal choice would be to use a foreign key, but since thats not possible I need to some up with something else.
So instead I created an IntegerField on the other database and tried using choices to get a list of available options.
class OtherDBTable(models.Model):
client = models.IntegerField(max_length=20, choices=Client.objects.values_list('id','name'))
the problem I'm having is that the choices seem to get populated once but never refreshed. How do I ensure that whenever the client list changes that those newest options area available to pick.
What I was really looking for was a way that I could simulate the behavior of a Foreign key field, at least as far as matching up ID's go.
There wasn't a clear way to do this, since it doesn't seem like you can actually specify an additional field when you instantiate a model (you can with forms, easily)
In any case to deal with the problem, since the database is MySQL based, I ended up creating views from the tables I needed in the other database.
To build on #Yuji's answer - if you do self.fields['field'].choices = whatever in the model's __init__, whatever can be any iterable.
This means you can inherit from iterable, and have that object interface to your legacy database, or you can use a generator function (in case you are unfamiliar, look up the yield keyword).
Citing a Django's manual:
Finally, note that choices can be any iterable object -- not necessarily a list or tuple. This lets you construct choices dynamically. But if you find yourself hacking choices to be dynamic, you're probably better off using a proper database table with a ForeignKey. choices is meant for static data that doesn't change much, if ever.
Why dont you want just export data from the legacy database and to import it into the new one? This could be done periodically, if the legacy database still in use.

Specifying default value for django hidden form field - bone DRY?

So let's say at the last minute (in the view) I decide I want to specify a default for a field and make it hidden, like so:
form.fields['coconut'] = forms.ModelChoiceField(
label="",
widget=forms.HiddenInput(),
queryset=swallow.coconuts.all(),
initial=some_particular_coconut,
)
My question is this: Do I really need to specify queryset here? I mean, I already know, from initial, exactly which coconut I'm talking about. Why do I also need to specify that the universe of available coconuts is the set of coconuts which this particular swallow carried (by the husk)?
Is there a way I can refrain from specifying queryset? Simply omitting causes django to raise TypeError.
If indeed it is required, isn't this a bit damp?
I think is good that stackoverflow answers point to the 'right' way to do things, but increasingly the original question goes unanswered because the user was trying to do the wrong thing.
So to answer this question directly this is what you can do:
form.fields['coconut'] = forms.ModelChoiceField(label="", widget=forms.HiddenInput(attrs={'value':some_particular_coconut}), queryset=swallow.coconuts.all())
Notice the named argument passed to HiddenInput, its super hackish but its a direct answer to the original question.
The problem is that you're trying to set up a hidden ModelChoiceField. In order to have a Choice (dropdown, traditionally) it needs to know its Choices - this is why you give a queryset.
But you're not trying to give the user a choice, right? It's a hidden input, and you're setting it from the server (so it gets POSTed back, presumably).
My suggestion is to try to find a way around using the hidden input at all. I find them a bit hacky. But otherwise, why not just specify a text field with some_particular_coconut.id, and hide that? The model's only wrapping that id anyway.
The reason django requires a queryset is because when you render the field to the page, django only sends the id. when it comes back, it needs knowlege of the queryset in order to re-inflate that object.
if you already know the queryset at form creation time, why not simply specify form.fields['coconut'].initial = some_particular_coconut in your view and leave the rest of the definition in your forms.py?
If you find that you only really need to send the id anyway (you don't have to re-inflate to an object at your end), why not send it in a char field?