0

Scenario:

I have a field named "editor" in my model "Questions" as below:

CHOICE_LIST = (('0', 'Undefined'), ('staffGroup', 'staffGroup'), ('staffGroup02', 'staffGroup02'), ('staffGroup03', 'staffGroup03'), ('staffGroup04', 'staffGroup04'), ('staffGroup05', 'staffGroup05'),)
editor = models.CharField(max_length=350, default=0, choices=CHOICE_LIST, verbose_name='Responsibility')

the editor field has a choice list which I manually defined from the names of user groups.

Problem:

  1. How can I generate the list directly from the auth_grup table?
  2. How can I selectedly do that (as I may not need all of them, I only may need those groups which starts with 'staff' string)
  3. How can I make this list static (so deleting an entry from usergroup may not delete it from the list) or dynamic (will dynamically update the list with the change in auth_group table)?
Mohammad
  • 657
  • 1
  • 7
  • 18

1 Answers1

0

Re 1: You can use a callable that returns all group. Example:

def getGroupNames():
    return Group.objects.all().values_list('name', flat=True)

You will still need to convert this to a tuple of ('short-name', 'human-readable-name')

If you want the same full names as short and human readable names in the tuple, you can do:

def getGroupNames():
    groups = Group.objects.all().values_list('name', flat=True)
    return zip(groups, groups)

And then use the same in the choice field

editor = models.CharField(max_length=350, default=0, choices=getGroupNames(), verbose_name='Responsibility')

Re 2: You can filter your query

def getGroupNames():
    return Group.objects.filter(name__starts_with='staff').values_list('name', flat=True)

Using choices is a presentation convenience. There is no restriction of the value that can be sent to the database, even coming from the front-end. For example, if you use the browser's inspect feature, you can edit the drop-down list, change one of the values and submit it. The back-end view will then happily consume it and save it to the database.

Meaning you will still be able to do this

obj = SomeModel.objects.get(pk=1)
obj.editor = 'Random Value not part of choices'
obj.save()

Re 3: The callable technique mentioned above is as static or as dynamic as you write it to be; this function will be evaluated when you make migrations and the values will be added as choices in the migration file. However, any serializers or forms that you write around this model will evaluate the choices time and time again.

Reference: https://zindilis.com/blog/2017/05/04/django-backend-validation-of-choices.html

rtindru
  • 5,107
  • 9
  • 41
  • 59
  • **Regarding #1** : How can I convert that into a touple? I have no problem if the '_short-name_' and the '_human-readable-name_' are same. **Regarding #2** : Not clear on the highlighted part, may be because I use forms.py to collect data. Can you give any reference on this so I can search or read more on this? Thanks a lot! Learnt a lot from your answer :) – Mohammad Apr 16 '18 at 16:23
  • @mahmudKabir Re 1: Just use zip; updated my answer with the same Re 2: The highlighted part says that even if you use choices, Django does not stop you from setting a value to that field on the model object. Django Forms, Admin, and Serializers will restrict you, but the model itself won't prevent save of non-choice values! – rtindru Apr 17 '18 at 06:02