Currently i have my models, views, forms in default file.
But i want to have directory structure like
articles
---------models
---------views
---------forms
Books
---------models
---------views
---------forms
Icecreams
---------models
---------views
---------forms
so that i keep separately but i don't want different app
The directory structure you describe is the individual apps directory structure. If you want it to look like that, you have to make them separate apps. However, you can do something like:
myapp/
__init__.py
models/
__init__.py
articles.py
books.py
icecream.py
Simply add a models directory and delete models.py. Then, create a separate .py file for each model/group of models you want to separate.
Here's the important part: on each of your models you must add the following to their Meta class:
class MyModel(models.Model):
...
class Meta:
...
app_label = 'myapp'
Where 'myapp', is the main app folder all these models are stored in.
Then, edit models/__init__.py and import all your models there, e.g.:
from .articles import Article
from .books import Book
from .icecream import IceCream
However, the models you list as examples are pretty obvious candidates for distinct apps. The approach above is really only for related models. If your models are truly that distinct, they should be individual apps.
... i don't want different app
But they are different apps, and so should be divided that way.
Related
I am trying to import a model from one app into another creating a new table etc.
# app1/models.py
class MyModel(models.Model):
myfield = models.CharField(...)
...
# app2/models/__init__.py
from app1.models import MyModel as MyShadowModel
What I would expect: python manage.py makemigrations would see changes in app2 and create the according tables.
Why does it not happen?
What would I have to do to achieve this?
Background
A Django project shall process Data and make changes visible. It consists of two apps:
app1 contains already processed data
app2 processes changes and shall show what data in app1 would look like.
The idea: app2 processes the data into a "shadow" model. Therefore i would like to use the exact same model as app1 in my models in app2
Importing the model doesn't suffice. Imagine you only have to do some logic with MyModel in app2's models.py. It doesn't make sense to create another table.
You have to declare another model that inherits from the parent model in order to replicate it.
from app1.models import MyModel
class MyShadowModel(MyModel):
...
Django-rest-frameworks (both tutorial and documentation) indicates to register routes as prefix-ViewSet pairs like so
# rapidsms_tut/rapidsms_tut/urls.py
#> (rapidsms_tut = project name)
#> (rapidsms_tut/rapidsms_tut = main/default app)
from rest_framework import routers
from voting import views
router.register(r'choices', voting.ChoiceViewSet) # choices is the url prefix (i.e. /choices/)
However I cannot find a way out of the following error (I'm making modifications to the rapidsms tutorial I've followed, but it doesn't really matter):
NameError at /choices
name 'voting' is not defined
/.../rapidsms_tut/rapidsms_tut/urls.py in <module>, line 12
My directory structure is as follows:
rapidsms_tut
rapidsms_tut
...
urls.py
voting
...
serializers.py
models.py # here we have Choice model
views.py # here we have CHoiceVIewSet ModelViewSet
voting/models.py
from django.db import models
class Choice(models.Model):
name = models.CharField(max_length=40, unique=True)
votes = models.IntegerField(default=0)
voting/views.py
from .models import Choice
from rest_framework import viewsets
from .serializers import ChoiceSerializer
class ChoiceViewSet(viewsets.ModelViewSet):
queryset = Choice.objects.all()
serializer_class = ChoiceSerializer
I guess the issue has something to do with directory structure / namespaces. Any clue?
Also, by following Django starter tutorial, I've been taught to have the default app (with settings.py, urls.py etc.) as a sub-folder of project folder (e.g. rapidsms_tut as sub-folder of rapidsms_tut).
However I've seen projects around with different apps but with urls.py, settings.py etc only in the root folder of the project (e.g. in rapidsms_tut and not default app's subfolder). What's the difference?
The issue is not related to importing the module or your dir structure, it's because voting is not defined in your code.
from voting import views
router.register(r'choices', voting.ChoiceViewSet)
You imported the views module from voting, not voting directly. You should change the route registration line to:
router.register(r'choices', views.ChoiceViewSet)
As for the second question, It's really a matter of preference, Django doesn't enforce you to use either structure. Here's the template I usually use for my projects: https://github.com/jpadilla/django-project-template
The settings.py and the main urls.py, are in the root project dir. I then make a sub dir called apps/, where all of the apps reside
I have a moderately complicated Django project with a variety of different apps (app1, app2 etc), each with their own models. I am building a MetaApp app to track info about each app, with a MetaApp class in models.py, and fields such as appname and modelname
MetaApp drives an index view that summarizes various aspects of each project. I would like to include a count of the database records for each app. This means that I need to programmatically access models from other apps. If I I know the appname and modelname, how do I programmatically access these models?
projects = MetaApp.objects.all()
projects[0].appname[0].modelname.ojects.all()
This code results in an attribute error, because I am storing the appname and modelname as unicode strings. What is the workaround?
Use the django.db.models.loading.get_model() function:
from django.db.models.loading import get_model
model = get_model(app_name, model_name)
object_list = model.objects.all()
I would like to separate my app's models in the admin index:
I registered all my models in admin.py and I get all of them in the default admin index under the big red 1 shown below.
Now I'd like to have some of my models in another "block", as shown below under the big red 2.
To make it harder, I also need to have some models in both "blocks", but with different queryset.
How can I do that?
I tested my solution and it works.
Do this:
class MyModelTest(models.Model):
# Fields here
class Meta:
app_label = 'My other app namespace'
UPDATE:
To achieve your goal (max flexibility) , you will need to modify the template admin/app_index.html and the view django.contrib.admin.sites.app_index to your own needs.
I've installed a django reusable app (Django-Userena) and would like to overwrite the given models.py file.
I have created an app named 'accounts' that calls from Django-Userena. In my 'accounts' app, I have this models.py file that has a class MyProfile that inherits from Django-Userena class UserenaBaseProfile - class MyProfile(UserenaBaseProfile)
In the UserenaBaseProfile class, there is the following code:
privacy = models.CharField(_('privacy'),
max_length=15,
choices=PRIVACY_CHOICES,
default=userena_settings.USERENA_DEFAULT_PRIVACY,
help_text = _('Designates who can view your profile.'))
I would like to extend privacy with an extra value with 'editable=False,' as I do not want this field to be displayed in the auto-generated form.
I tried several ways like calling privacy again in the MyProfile inherited model with the new settings but I am only made aware of Django's "Field name "hiding" is not permitted" (https://docs.djangoproject.com/en/1.4/topics/db/models/#field-name-hiding-is-not-permitted)
My current solution is to simply include the whole UserenaBaseProfile class in my 'accounts' app models.py before calling class MyProfile(UserenaBaseProfile) below.
This does not look like an elegant solution to me. How do you guys go about overriding the models.py file in the reusable app?
Thank you very much.
In my opinion it could be done in two ways:
Make a fork of Django-Userena with your modified model and you use yours.
Make a wrapper of Django-Userena with your models.py and use your wrapper app.
For the urls.py/views.py you could just put:
#Your wrapper views:
from django-userena.views import *
#your wrapper urls:
from django-userena.urls import *
Here are your models:
#your MODIFIED model:
from django-userena.models import *
# then put you new UserenaBaseProfile
class UserenaBaseProfile(models.Model):
#copy the model fields
...
privacy = models.CharField(_('privacy'),
max_length=15,
choices=PRIVACY_CHOICES,
default=userena_settings.USERENA_DEFAULT_PRIVACY,
help_text = _('Designates who can view your profile.'))
Then you could use your custom app in your project.
If you want to customise templates, create a templates directory in your project and put there your modified template files keeping their original names, so the django template-loader could find yours first (it depends how template-loaders have been configured in your settings.py)