1đź‘Ť
Scenario 1 doesn’t make sense. You’re using the constants to specify the verbose_name
of the fields, and you’re using them in the list_display
option. The list_display
option takes a list of fieldnames and NOT the verbose_name
of the fields.
So you don’t need constants at all for this. The field names are your “constants”.
And IF you would need some “constants” in some case, you shouldn’t use methods, just use properties, and just use normal class/attribute name conventions (so no uppercases):
class SomeConstants():
name = "name"
surname = "surname"
zipcode = "zipcode"
city = "city"
created = "created"
The Java/PHP guys might say something like “Yeah but what if one of the constants needs to be generated? Then you need a method!”. Well, sure, so you make it a property:
class SomeConstants():
@property
def full_name(self):
return "{} {}".format(self.name, self.surname)
Because of the @property
line above the method, it will execute and return the result of this method if you call SomeConstants().full_name
.
2đź‘Ť
Scenario 1 is awful. Unfortunately I know all too well the problems of working with Java/PHP developers who are learning python.
Perhaps you can compromise with those guys by proposing the use of python enums to address their concern. These are built-in in python 3.4+, and have been backported as far back as 2.4.
from enum import Enum
class Constant(Enum):
name = "name"
surname = "surname"
zipcode = "zipcode"
city = "city"
created = "created"
Now you can change the “values”, say for example changing zipcode to be “potato” in the enum definition, whilst still using the name Constant.zipcode.value
everywhere else in source code.
- [Django]-Django database charset issue
- [Django]-How can I set salt for bcrypt.hashpw?
- [Django]-How to use autobahn.ws with django?
- [Django]-Django Custom widget rendering
- [Django]-Django meta permissions
1đź‘Ť
Use of constants is sometimes good, but not here.
One, the first argument of a field is its verbose name, if it’s missing then the name of the field is used by default. So using the same constant for its verbose name as for the field name is exactly the scenario in which the verbose name is completely unnecessary.
Just do
name = CharField(max_length=25)
or
name = CharField("A beautiful description for a name field", max_length=25)
but putting “name” there is completely redundant and thus wrong. Don’t repeat yourself.
Second, your constant is actually used for two different things that you don’t want to change at the same time: you use the same constant for the attribute name in admin.py, but for verbose name in models.py. They aren’t going to stay the same thing.
Third, using constants is only really helpful if the value might change one day, or if it’s not immediately obvious what it may mean, for e.g. PI=3.14.
But NAME = "name"
does not make anything more obvious, and if it ever changes to NAME = "description"
it immediately becomes actively misleading. You’d probably want to change the name of the constant in that case as well, won’t you? Why did you ever use a constant then?
And it means that changing something in const.py
changes the database structure that Django expects. Some day a developer is going to trip over that; keep field names in models.py
.
Finally, at every place where you use the models, you need the actual field anyway. A Register
instance is simply a class instance, after all, and you’ll probably want to use fields like register.name
anywhere. You don’t put the names of attributes of other classes in constants, do you?
Just use the string.
- [Django]-DJANGO – Change text color based on value (HTML & JS)
- [Django]-What is a good way to get the dynamic title of a page in Django?
1đź‘Ť
What about something more straight-forward like:
constants.py
NAME = "name"
SURNAME = "surname"
admin.py
import constants
class RegisterAdmin(admin.ModelAdmin):
list_display = (constants.NAME, constants.SURNAME,constants.ZIPCODE)
This provides a unique place for the values in contrast to repeating them as in Scenario 2 and thus I would prefer it. It seems more clear than Scenario 1 to me. The “encapsulation” is performed by the module name, i.e. by using constants.xxx
, so don’t from constants import *
.
The values here are obviously not constant, but neither are they in Scenario 1.
- [Django]-Fake subfunction in django UnitTest Case (Mocking)
- [Django]-SMTPAuthenticationError: (535, b'5.7.8 Username and Password not accepted in Django production?
- [Django]-Django – how to send mail 5 days before event?
0đź‘Ť
Everyone is in agreement that its a bad idea, but it could be that your Java friends are trying to implement the equivalent of a Java resource bundle, perhaps because they fondly remember how easy it is to work with .properties
files.
This results in the use of keys in place of actual names and then later on the system will retrieve the correct resource from the bundle. This technique is used for translations and localization of applications.
A typical resource key looks like key.trx.hist.term.transfer.completed.success
and at runtime the equivalent resource is rendered by the application.
If this is the case, in Python the approach is a bit different:
- You start with a base language. This is what you write your code in.
- All strings that need to be localized or translated are marked for translation, with the
gettext
library. For convenience this library provides a shortcut method_()
which is used to mark strings for translation. - These strings are then extracted to a message file; which is forwarded to translators. The message file contains the file names where the string is used. Its a plain text file, much like the .properties file.
- This message file is then compiled into an optimized format.
- Based on the language/locale of the client, the correct translated strings are displayed.
You can read more on how this is implemented in django at the translation documentation.
- [Django]-How to deploy media files in django-heroku?
- [Django]-AttributeError: 'module' object has no attribute 'Datefield'