I am outsourcing my models into packages in order to have a better overview. So the models.py of my app main looks like
from django.db import models
from models import *
And the actual models are in models/user.py, ...
So when I go back to prepare a migration:
python manage.py makemigrations main
Django won't detect any changes. Why?
I had the same problem with migrating my models. so i changed the import methodology and instead of
from models import *
i tried this
from models.user import User, Device, ...
and it worked
Django looks into 'appname/models.py'. If you want this structure, you can use 'appname/user/models.py' and in INSTALLED_APPS 'appname.user', but it's better to use flat design: 'appname/models.py', 'user/models.py', ...
Related
I am building an app that displays different courses. For each course there is a list of the different classes it has.
Some courses have two classes, some have eight, some have just one or in the future some courses may have 10 classes. It's up to the app's administrator when they register a new course
class Curso(models.Model):
clases = models.IntegerField(default=1)
content = ArrayField(models.CharField(max_length=30),blank=False)
This model will only be for the administrator.
I want to store the different classes (just their names) in an array. But there's no need to show 8+ fields if the admin is just going to fill one in... Or is that the correct approach?
I want the admin to have an integer field where she types in how many classes the course has and depending on that the array fields will be displayed.
I understand ArrayField has a size attribute where I can say how long the array is. Right? So my question is:
Is there a way to dynamically change the array size depending on what the admin types in in the "clases" field?
I need this to work in the admin app. I am new to Django and I'm finding the admin app a little bit hard to manipulate.
Well I did my research. And this is how it turned out:
models.py
from django.db import models
from django_better_admin_arrayfield.models.fields import ArrayField
# Create your models here.
class Course(models.Model):
...
clases = ArrayField(models.CharField(max_length=10),null=True,blank=True, size=8)
...
Turns out I just needed to use ArrayField with django-better-admin-arrayfield
It doesn't do exactly what I described in this question, but it works just as fine (even better) to visually edit the arrayfield in the admin page
Here's the repository django-better-admin-arrayfield
You just need to pip install it and then add it to your settings.py installed apps
INSTALLED_APPS = [
...
'django_better_admin_arrayfield',
...
In admin.py
from django.contrib import admin
from .models import Course
from django_better_admin_arrayfield.admin.mixins import DynamicArrayMixin
#admin.register(Course)
class CursoAdmin(admin.ModelAdmin, DynamicArrayMixin):
...
And that was it! makemigrations and migrate and... It didn't work. The problem was the add another button wasn't working. So I read the issues in the repo and someone wrote you should run collectstatic and it worked!!
Shout out to #nbeuchat, whoever that is, that who's answer in in this stackoverflow post was the only thing that helped me get out of this problem
I've looked into the source code for some django model fields, in this case DateTimeField. In the tutorial for Django, we are taught to create a DateTimeField like this:
from django.db import models
field = models.DateTimeField()
But looking in the source code, the file where DateTimeField is defined is django/db/models/fields. So, intuitively, if I were to import the field, I would write from django.db.models.fields import DateTimeField.
Do you see the difference? In the tutorial, they import it from django/db/models, while it looks like from the location of the source code that it actually resides in django/db/models/fields. Why doesn't the tutorial way of importing DateTimeField crash?
The fields are imported in django/db/models/__init__.py
Take a look at the source code.
Possibly relevant: What is init.py for?
I am creating django permissions based on django views rather than basic model based permissions. Hence I want to get the list of all the classes in a view. I tried the following:
from django.apps import apps
apps.get_app_config('my_app')
And also:
import sys, inspect
inspect.getmembers(sys.modules['my_app'], inspect.isclass)
But I didn't get classes object.
apps.get_app_config('my_app').get_models()
will return a list of all models declared in your application.
if you want to get all models including those in INSTALLED_APPS you can
appconfigs=apps.get_app_configs()
for appconfig in appconfigs:
models = appconfig.get_models()
On documentation it has been said that each model is a python subclass of models.Model class that is inside django folder followed by db folder. When i look inside my django folder i see a db folder which was expected and inside my db folder i see models folder which contains lot of files. But I was expecting a models.py package which contains Model class. So my doubt is from where does this models.Model class come from?
This might be not a top level question but I am hopeful someone here will certainly help.
Nope it's not magic it's django , it does exist if you go to the django's source code, you can see that the Model class exists, But in that way don't you had to import models in this way??:
from django.db.models.base import Model
Yes you can do it in that way, But django does it for you in the models/__init__ file, so the only thing you have to do is:
from django.db import models
models refers to the models folder inside django.db but when you import it, it brings you all the things that are inse the models/____init__.py file, I recommend you to read this
I have many apps and i want to activate the admin for all the models in my all apps.
I remember few months one of my friend did something that enables the admin site without any admin.py file
he did something in settings.py files with INSTALLED_APPS and all of the apps showed in the admin section
I am now not able to find that. Any one??
Your friend probably did something like...
from django.db.models import get_models
for model in get_models():
admin.site.register(model)
In one of his admin.py files.
I dunno, I'd only do this to test stuff. It's a bit too magical. Remember you'll have to explicitly unregister any models you may want to register again.
Just follow the instructions in the docs. They describe how to activate the django admin site here. You need to modify urls.py. That's it.
There are even comments in that file that tell you which three lines to uncomment.
I recommend you do include an admin.py in your apps because it is the Django convention and that some explicitness in what you trying to achieve is a good thing; the solution I use is the following default admin.py template for all new apps I start:
# Auto registers any new models with the admin, eventually you will want a tailored admin.py
from django.contrib import admin
current_app = models.get_app(__package__)
for model in models.get_models(current_app):
admin.site.register(model, admin.ModelAdmin)