Use CharField choices not only in admin - django

I've got a model with a property which represents the current status of something.
STATUSES = (('status1', 'The first status'),('status2', 'The second status'),('status3', 'The third status'))
status = models.CharField(choices=STATUSES)
When using Django-Admin, the choices (i.e. "The first status") is displayed instead of the values (i.e "status1"). How can i achieve this when printing out the status in one of my templates? Or is there any better model field to use in this case?
I know I could just use the same string in both elements in the tuples in STATUSES, but this seems like quite bad practice and makes it hard to rename choices if needed.

To display the human readable version of the currently selected choice, use:
{{ instance.get_myfield_display }}
http://docs.djangoproject.com/en/dev/ref/models/instances/#django.db.models.Model.get_FOO_display

Related

Django - What is the best way to store in the DB answers that can be numerical or text?

I'm working on a student survey project. The model that stores the questions is something like:
ID Question Type
1 is good teacher? Choice
2 What do you like about Open-answer
the teacher?
Then in the choice type questions the student will choose an option (e.g.: fully agree) and this will store a numerical code (e.g. 5). But in the open-answer questions , the student will write text.
what kind of field should store these answers in the answers model? maybe TextField?
You ur choices as text if you want to use same column to open text... so instead of set 1,2,3,4 you can write a fixed text when user select the options, so this make your data more readeble
ANSWER = (
("Yes", "Yes"),
("No", "No"),
("Neutral", "Neutral"),
)
Or make 2 more columns... one to set type of question (select or text) and the other to store the options (that way you can setup as foreign key and instead of use static values this can be loaded from one model)
ID Question Type Answer-Text AnswerID
1 is good teacher? Choice null 1
2 What do you like about Open-answer "The way he swag" null
the teacher?
Or mix everything with String... but you will have some troubles getting this integer ids... will throw some erros when you try to get it as integer int("1") Will work but int("The way he swag") will raise a error
Using a TextField would probably be a bad idea since you're mixing int with string type objects which is definitely not recommended.
One thing you could do is consider this as two different fields. One Choicefield and one TextField. That way the user can choose an empty value (empty string '') when he wants to use the open-answer. You can then compute empty strings as being nothing later on.

Setting Django DateRangeField parameters

I need to track people in their current positions. So in my model I can do:
tenure = models.DateRangeField(‘date of hire’, ‘date of termination’)
but what about someone who is currently still employed? Can I do:
tenure = models.DateRangeField(‘2006-10-10’, datetime.date.today())
or
tenure = models.DateRangeField(‘2006-10-10’, [)) ?
Then when this person terminates, I can change the value on the instance to a date certain, but will that cause a problem because the model field expects a function?
Eventually I am going to have to query against this date range, which is why I was looking at the new DateRangeField, but maybe I'd be better off with two plain date fields, one for start and one for termination?
DateRangeField takes the standard model field keyword arguments. The first two arguments would be interpreted as Field.verbose_name and Field.name based on the signature of Field.__init__(). It seems that you think it takes some arguments with some other meaning.

How to create linked (associated) automatically updated form fields in GAE Django

I am new to Django and GAE. I would like to create two input fields, where the first one is a drop-down menu (let name it select), which decides the values in the second one (let name it val).
For example, once 'A' is chosen from 'select', field 'val' will show '1'. similarly, 'B' is associated to '10'. I have written several lines below, but it does not work. Two issues:
The second field ('val') always equals 0.
It seems like my second field ('val') does not 'listen' to the choice made by the first one ('select'), which means those two fields are not linked.
Can anyone give me some suggestions (or recommend books on using Django on GAE)? Thank you!
select_CHOICES=(('A','A'),('B','B'),('Other','Other'))
select = forms.ChoiceField(choices=select_CHOICES, initial='A')
def get_choices(select):
if select=='A':
r= 1
elif select=='B':
r= 10
else:
r= 0
return r
val=forms.FloatField(initial=get_choices(select))
I think you have understood how django works a bit wrong. The code that you input is run before the page is rendered, so no selection is made yet. If you want the input field to dynamically change as user makes the choise on page, you should use Javascript.
Also you are comparing a Field (select) to a string ('A'), which naturally always is unequal.
Read more documentation and tutorials and you'll soon get how it works.

Django annotate according to foreign field's attribute

I normally use something like this "Tag.object.annotate(num_post=Count('post')).filter(num_post__gt=2)" to get tags with more than 2 posts. I want to get number of posts with a field value (e.g post.published=True) and annote over them so that I get tags with number of published posts bigger than some value. How would I do that?
Edit:
What I want is not filter over annotated objects. What I want is something like this: Tag.objects.annotate(num_post=Count("posts that have published field set to true!")). What I am trying to learn is, how to put post that have published field set to true in Count function.
You can just replace the 2 in ..._gt=2 with some other variable - for example, a variable that gets passed into the view, or a request.GET value, or similar.
Is that what you're trying to do?

Select DISTINCT individual columns in django?

I'm curious if there's any way to do a query in Django that's not a "SELECT * FROM..." underneath. I'm trying to do a "SELECT DISTINCT columnName FROM ..." instead.
Specifically I have a model that looks like:
class ProductOrder(models.Model):
Product = models.CharField(max_length=20, promary_key=True)
Category = models.CharField(max_length=30)
Rank = models.IntegerField()
where the Rank is a rank within a Category. I'd like to be able to iterate over all the Categories doing some operation on each rank within that category.
I'd like to first get a list of all the categories in the system and then query for all products in that category and repeat until every category is processed.
I'd rather avoid raw SQL, but if I have to go there, that'd be fine. Though I've never coded raw SQL in Django/Python before.
One way to get the list of distinct column names from the database is to use distinct() in conjunction with values().
In your case you can do the following to get the names of distinct categories:
q = ProductOrder.objects.values('Category').distinct()
print q.query # See for yourself.
# The query would look something like
# SELECT DISTINCT "app_productorder"."category" FROM "app_productorder"
There are a couple of things to remember here. First, this will return a ValuesQuerySet which behaves differently from a QuerySet. When you access say, the first element of q (above) you'll get a dictionary, NOT an instance of ProductOrder.
Second, it would be a good idea to read the warning note in the docs about using distinct(). The above example will work but all combinations of distinct() and values() may not.
PS: it is a good idea to use lower case names for fields in a model. In your case this would mean rewriting your model as shown below:
class ProductOrder(models.Model):
product = models.CharField(max_length=20, primary_key=True)
category = models.CharField(max_length=30)
rank = models.IntegerField()
It's quite simple actually if you're using PostgreSQL, just use distinct(columns) (documentation).
Productorder.objects.all().distinct('category')
Note that this feature has been included in Django since 1.4
User order by with that field, and then do distinct.
ProductOrder.objects.order_by('category').values_list('category', flat=True).distinct()
The other answers are fine, but this is a little cleaner, in that it only gives the values like you would get from a DISTINCT query, without any cruft from Django.
>>> set(ProductOrder.objects.values_list('category', flat=True))
{u'category1', u'category2', u'category3', u'category4'}
or
>>> list(set(ProductOrder.objects.values_list('category', flat=True)))
[u'category1', u'category2', u'category3', u'category4']
And, it works without PostgreSQL.
This is less efficient than using a .distinct(), presuming that DISTINCT in your database is faster than a python set, but it's great for noodling around the shell.
Update:
This is answer is great for making queries in the Django shell during development. DO NOT use this solution in production unless you are absolutely certain that you will always have a trivially small number of results before set is applied. Otherwise, it's a terrible idea from a performance standpoint.