I have seen people writing forms in models or in forms.py? Is it the case I can actually write it anywhere say in blah.py and just import it wherever necessary?
That's correct. It's just like any other python class, you can define your form classes in whichever file you prefer. However, it is often considered best practice for Django to put them in a file like APP/forms.py.
yes, you can put it anywhere provided that you can import it
You can, but it's better to put forms declarations in forms.py in order that other developers could feel familiar in your project.
Related
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.
I was reading over the following code, and the models were structured such that each class/model had a separate file and then it was imported in __init__.py. For example:
# __init__.py
from service import Service
from note import Note
etc...
# service.py (one example of the imports)
from django.db import models
class Service(models.Model):
#: service provider name (e.g. Hulu)
name = models.CharField(max_length=64, verbose_name="Title Name", unique=True)
def __unicode__(self):
return u'Service id=%s, name=%s' % (self.pk, self.name)
Which way is better practice, to have all models in one models.py file, or to have one file-per model? I usually keep all my models for an app in one file, and I had never seen the models separated, which is why I'm asking this question.
If you're talking true "best practice", that would be following the way Django recommends and using just models.py. However, there's a lot of opinion and argument that goes into the this topic. Nevertheless, my recommendations:
If you have a simple app, with only a few models. Stick with the "Django-way" of just a models.py.
If you have a huge app with lots of models and thousands of lines of code, divvying it out is probably better. However, at this point, you should also ask yourself why your app is so huge and if anything can be factored out into auxiliary apps.
Long and short, my personal opinion is that breaking out of the models into separate files is never a good idea. It can in some cases cause problems and I honestly can't see a use case where it's truly justified. Usually, if your app is big enough to warrant doing this, it's actually a sign that you're lumping too much functionality together that would be better delegated out into other apps.
Best practice is to put them in one file. Look at the django source for example.
The reason you've never seen it is because it's practically never done.
If you can justify it somehow then by all means do it, but it's definitely not the recommended structure. People start to explore splitting models when the file gets too large / can be logically separated.
I have a bunch of functions that I created in some views that must be reused in many other views. Do I need to create a class and put those functions in a class? If yes how exactly has to be done in Django and then how do I call and initiate them in the new views?
Django views are just Python functions. You can call other Python functions from them just as you can from any other Python code. Put your functions into a .py file, import it, and invoke the functions.
Of course, it may make sense for other reasons to create a class to hold the functions, but you certainly don't need to in order to call them from views.
The solution would be to create the myfunctions.py file in your app folder and import it in your views. Your views file would look like:
import myfunctions
def my_view(request):
.....
foo = myfunctions.bar()
....
You look to complicated to Django. Django is just another Python application and lives in the Python world. For example you can create file library.py and import this file where is needed (in modules where the function from library is needed). If you need you library's functions to get data from database, just import models in the library.py and use them.
Django doesn't have such a big think as "module". You creating the architecture, you can define what in your case is module. In general this is just simple directory with init.py file inside to be able to import files from there.
Hope that helped.
From my point of view, if you have a lot of functions that are widely used in your project it make sense put all this in some separate application. I create some module named 'contrib' for this purposes. It can avoid some time for maintaining this code in future
I like Eclipse for a number of reasons. One of them is, when I'm doing a java project, I can copy and paste my project or rename it, to make a new one, and it will update all the names of everything.
I'm trying to do something similar for a django project.
I can set an APPNAME variable with the following code
APPNAME = os.path.basename(os.path.dirname(__file__))
and then I could import this in any file that needed to know the name of the application. This isn't an ideal solution however but it would work for my settings.py file as well as my urls.py files.
It won't work for situations where I need to import something from somewhere like so:
from myproject.someapp import forms
Is there a way for django/python to know what "myproject" is? Or can I use an import statement relative to the current app?
Or maybe there's a better way to copy django projects.
EDIT: I imagine there are also database dependencies as well that I'd have to deal with.
I follow a couple of rules to keep my applications portable. I'll list them below in the hope that someone finds them useful.
Include my apps in the PYTHONPATH rather than my projects. This way I can execute from app import forms rather than from project.app ....
Following #1, I always import from app only. This means I can reuse my apps in other projects without having to change import statements within the app or in other dependent apps.
If you stick to #1 and #2 you can generally copy and paste projects without too much trouble. You'll still have to modify settings.py though.
This is really just a "best practices" question...
I find that When developing an app, I often end up with a lot of views.
Is it common practice to break these views up into several view files? In other words... instead of just having views.py, is it common to have views_1.py, views_2.py, views_3.py (but named more appropriately, perhaps by category)?
Splitting views.py
Most of your code probably expects your views to be accessible as myapp.views.viewname. One way I've seen people break up their views but keep this python name is to create a views/ directory. views/__init__.py will have:
from .foo_views import *
from .bar_views import *
from .baz_views import *
Then, in views/foo_views.py, put:
def foo_detail(request, ...):
# your code here
def foo_list(request, ...):
# your code here
def your_other_view(...):
# ...
etc. So you move everything from views.py into files in this directory, make __init__.py, delete views.py, and you're done.
Then, when you import myapp.views, myapp.views.foo_detail will refer to the function that you defined in views/foo_views.py.
Splitting other modules
This strategy should also work fine for admin.py, etc. But if you want to split up models.py like this, you will need to add app_label = 'your_app_name' to the class Meta: of all of your models. For example, unicorn_app/models/unicorns.py could have an entry like this:
class Unicorn(models.Model):
description = models.CharField(max_length=80)
class Meta:
app_label = 'unicorn_app'
(Otherwise, Django imagines that the Unicorn model is part of a Django app named "models", which messes up the admin site. Current through 1.6 - the upcoming 1.7 release will remove this requirement.)
As a general guideline, think about readability and maintainability: the default "views.py" is just a suggestion made by initial scaffolding - you do not have to stick to it.
Usually, files with thousands of lines of code are difficult to maintain, for this I usually try to decompose bigger modules into smaller ones.
On the other hand, the division should make sense - splitting related functions into several files, with lots of imports may make maintenance even more difficult.
Finally, you can also think about completely other ways to simplify your application.
Do you see duplicated code? Maybe some functionality could be moved in a completely different application? And so on.
Another option would be to move some of the functionality into one or more apps. This would allow you to move also forms and templates and keeping things structurized. You don't necessarily need to move the models which saves you from model and data migration.
For example you could have the following structure:
main_app/
|_models.py
|_views.py
|_forms.py
|_urls.py
|_templates/
sub_app_1/
|_views.py
|_forms.py
|_urls.py
|_templates/
sub_app_2/
|_views.py
|_forms.py
|_urls.py
|_templates/