Django model name with underscore? - django

I have subtly different entities that are important enough with respect to the relationships, flexibility, and expression of my schema that they warrant separate models.
How should I name/ case these?
a) Layerinput, Layerhidden, Layeroutput
b) Layer_Input, Layer_Hidden, Layer_Output
c) LayerInput, LayerHidden, LayerOutput
Right now I am leaning option a so that Django doesn't do anything too automagically incorrect with them, but that won't look great in documentation and code. Will use them with either DRF or graphql.

If you're referring to naming Classes, you should choose c) as shown in image below (obtained from https://docs.djangoproject.com/en/2.1/topics/db/models/#verbose-field-names).
If you're referring to the field_names (eg. name and age under the class CommonInfo in the figure above), then the convention for django is as followed:

According to PEP8 conventions,
Class names should normally use the CapWords convention.
These naming conventions are also followed in the Django framework. So you can choose the third option.

Use camelCase (option c), this helps you differentiate words in a variable while minimising the characters (as in option b)
Use this as a guide: https://docs.djangoproject.com/en/dev/internals/contributing/writing-code/coding-style/

CamelCase (option c) is also useful because Django will know how to render your model names in the admin site. For example 'LayerInput' will appear correctly as 'Layer input' without you having to specify it anywhere.

Related

Is there a wrong way to name Class Based Views in Django?

this is a question about code style and best practices.
In our Django project we have Class Based Views named like this:
urls.py
path('project/<int:pk>/clone/', CloneView.as_view(), name='clone'),
path('project/<int:pk>/delete/', ProjectDelete.as_view(), name='project-delete'),
path('project/<int:pk>/optimize/', ProjectOptimize.as_view(), name='project-optimize'),
path('project/<int:pk>/report/', ReportView.as_view(), name='report'),
as you can see, some of them we say MyClassView.as_view() and in others we just say MyClass.as_view(). But I also noticed that in the Documentation they always use the first form: https://docs.djangoproject.com/en/2.2/topics/class-based-views/
Something that also caught my attention is that we never use view in the name, for example: name=clone-name.
My question is: is there any noticeable advantage of explicitly saying in the class name that this class is a view? Is it "wrong" not to use it?
I would like to keep our code base consistent.
Thank you all!
I don't think it really matters whether or not you include the View suffix. It's common to include the name in Django projects, but the most important thing it to be consistent across your own project.
One advantage of using the View or Form suffix is to avoid name clashes. For example BookView, BookForm and the model Book can't clash with each other.
You can avoid clashes by importing modules instead of objects, in which case the Form and View suffixes are not necessary.

Specify typing for Django field in model (for Pylint)

I have created custom Django model-field subclasses based on CharField but which use to_python() to ensure that the model objects returned have more complex objects (some are lists, some are dicts with a specific format, etc.) -- I'm using MySQL so some of the PostGreSql field types are not available.
All is working great, but Pylint believes that all values in these fields will be strings and thus I get a lot of "unsupported-membership-test" and "unsubscriptable-object" warnings on code that uses these models. I can disable these individually, but I would prefer to let Pylint know that these models return certain object types. Type hints are not helping, e.g.:
class MealPrefs(models.Model):
user = ...foreign key...
prefs: dict[str, list[str]] = \
custom_fields.DictOfListsExtendsCharField(
default={'breakfast': ['cereal', 'toast'],
'lunch': ['sandwich']},
)
I know that certain built-in Django fields return correct types for Pylint (CharField, IntegerField) and certain other extensions have figured out ways of specifying their type so Pylint is happy (MultiSelectField) but digging into their code, I can't figure out where the "magic" specifying the type returned would be.
(note: this question is not related to the INPUT:type of Django form fields)
Thanks!
I had a look at this out of curiosity, and I think most of the "magic" actually comes for pytest-django.
In the Django source code, e.g. for CharField, there is nothing that could really give a type hinter the notion that this is a string. And since the class inherits only from Field, which is also the parent of other non-string fields, the knowledge needs to be encoded elsewhere.
On the other hand, digging through the source code for pylint-django, though, I found where this most likely happens:
in pylint_django.transforms.fields, several fields are hardcoded in a similar fashion:
_STR_FIELDS = ('CharField', 'SlugField', 'URLField', 'TextField', 'EmailField',
'CommaSeparatedIntegerField', 'FilePathField', 'GenericIPAddressField',
'IPAddressField', 'RegexField', 'SlugField')
Further below, a suspiciously named function apply_type_shim, adds information to the class based on the type of field it is (either 'str', 'int', 'dict', 'list', etc.)
This additional information is passed to inference_tip, which according to the astroid docs, is used to add inference info (emphasis mine):
astroid can be used as more than an AST library, it also offers some
basic support of inference, it can infer what names might mean in a
given context, it can be used to solve attributes in a highly complex
class hierarchy, etc. We call this mechanism generally inference
throughout the project.
astroid is the underlying library used by Pylint to represent Python code, so I'm pretty sure that's how the information gets passed to Pylint. If you follow what happens when you import the plugin, you'll find this interesting bit in pylint_django/.plugin, where it actually imports the transforms, effectively adding the inference tip to the AST node.
I think if you want to achieve the same with your own classes, you could either:
Directly derive from another Django model class that already has the associated type you're looking for.
Create, and register an equivalent pylint plugin, that would also use Astroid to add information to the class so that Pylint know what to do with it.
I thought initially that you use a plugin pylint-django, but maybe you explicitly use prospector that automatically installs pylint-django if it finds Django.
The checker pylint neither its plugin doesn't check the code by use information from Python type annotations (PEP 484). It can parse a code with annotations without understanding them and e.g. not to warn about "unused-import" if a name is used in annotations only. The message unsupported-membership-test is reported in a line with expression something in object_A simply if the class A() doesn't have a method __contains__. Similarly the message unsubscriptable-object is related to method __getitem__.
You can patch pylint-django for your custom fields this way:
Add a function:
def my_apply_type_shim(cls, _context=None): # noqa
if cls.name == 'MyListField':
base_nodes = scoped_nodes.builtin_lookup('list')
elif cls.name == 'MyDictField':
base_nodes = scoped_nodes.builtin_lookup('dict')
else:
return apply_type_shim(cls, _context)
base_nodes = [n for n in base_nodes[1] if not isinstance(n, nodes.ImportFrom)]
return iter([cls] + base_nodes)
into pylint_django/transforms/fields.py
and also replace apply_type_shim by my_apply_type_shim in the same file at this line:
def add_transforms(manager):
manager.register_transform(nodes.ClassDef, inference_tip(my_apply_type_shim), is_model_or_form_field)
This adds base classes list or dict respectively, with their magic methods explained above, to your custom field classes if they are used in a Model or FormView.
Notes:
I thought also about a plugin stub solution that does the same, but the alternative with "prospector" seems so complicated for SO that I prefer to simply patch the source after installation.
Classes Model or FormView are the only classes created by metaclasses, used in Django. It is a great idea to emulate a metaclass by a plugin code and to control the analysis simple attributes. If I remember, MyPy, referenced in some comment here, has also a plugin mypy-django for Django, but only for FormView, because writing annotations for django.db is more complicated than to work with attributes. - I was trying to work on it for one week.

Are there database standards in Symfony and Doctrine?

Symfony uses a set of coding standards to set out for us how to program and what style we should use. My question is short and simple. I would like to know if symfony (together with doctrine ORM) has a similiar set of standards when it comes to building and structuring my database.
For example:
Should I use Camel Case?
Should my table name be user or users
Do I use capitals?
What charset is recommanded?
Basically, you do not need to care about database naming as Doctrine will do everything for you.
You should use Doctrine cli commands to generate your database schema based on your entities, or even better use Doctrine Migrations to maintain changes.
Should I use Camel Case?
For entity class names, I'd recommend sticking with PSR, so yes, use CamelCase.
Symfony by default uses underscore naming strategy, so entity CamelCase will be generated as table camel_case (if not manually overriden).
You can set another naming strategy, but the default underscore strategy is a fine choice.
Should my table name be user or users
user is a ANSI SQL reserved word, so I recommend using users. Or, if you prefer having entities in singular, try person instead.
Do I use capitals?
Again, Doctrine naming strategy will solve this for you. Moreover, eg postresql converts all table names and such identifiers to lowercase, so using capitals explicitly can cause problems.
What charset is recommanded?
Use UTF-8 (or more specifically utf8mb4 if needed). There are few reasons to use any other.

naming conventions for DynamoDB?

Background: I'm creating kind of simplified pseudo-ORM for use in Django. Classes obviously use CamelCase convention, while Django app is underscored lowercase. Which leaves me with a few options:
Django ORM style: app_name_someclass
proper underscore style: app_name_some_class
as-is: app_name.SomeClass
possibly some other using different separators etc.
Are there any well established naming conventions for DynamoDB?
So far, from what I've seen in examples, it seems that it's free-for-all.
Following the examples in the AWS documentation here and here would lead to the following conventions:
Table names in Upper Camel Case, e.g. MyTable.
Attribute names also in Upper Camel Case, e.g. Id, ProductCategory etc.
Actually the examples are a bit inconsistent when it comes to acronym capitalization - with ISBN and Id in the first link and both CustomerID and CustomerId in the second link. Either style could be argued but I'd personally lean towards only capitalizing the first letter in an acronym. See here for more debate on this subject.
It's free for all. I name tables as "users", "secret-files", "seen-blog-posts", and their attributes as "user.name", "date.recent.iso", etc.

Django class naming convention regarding abbreviations

Is there an existing naming convention for using abbreviations in Django classes (e.g. models, forms, etc)? Specifically I'm interested if there's different rules between abbreviations/acronyms/initialisms?
So far I've only found examples of non-acronyms:
XMLField
HTTPRequest
What should a JSON field be called (since it's an acronym)?
JSONField, or
JsonField
From PEP 8:
Use JSONField over JsonField.
Since CapWords are used for class names, this comment applies:
Note: When using abbreviations in CapWords, capitalize all the letters
of the abbreviation. Thus HTTPServerError is better than
HttpServerError.