Django Moving Models - python

I have a django application I'm trying to refactor. There's a million and five ways it seems to migrate models from an existing django app to a new one however I wanted to run by what seems like the easiest solution.
Let's say my current application is called 'main-app' in said application i have a model 'user'. This would create a table called 'main-app_user' or something similar.
Let's say I want to move the user model to a new app 'core', some tutorials state this is as easy as pointing the new model to the old table like so
class User(models.Model):
...
class Meta:
db_table = 'main-app_user'
I was curious if there was any catch to this I suppose? Many tutorial make this way more complicated so I'm curious why this isn't just the de-facto solution or if there are any drawbacks to this vs others. Thank you in advance!

Related

Django apps , functionalities and models

This is a pretty beginner question, as i have recently learned Django,
I have these questions since i could not find a clear answer for any.
Suppose that we want to build a voting system, and we have users with votes, i have a confusion with the admin user, i should create an app called users? or i should use the users default table by django?
for each app i'll have a model, and for sure database-wise, for example a user will have many votes on many projects, therefore how can i connect these relationships across models in the right way?
Thanks in advance
You don't have to create an app for each model. An app is usually a self-contained, useful entity, that you separate from other apps if you think you'd reuse it in another project in the future. In your case, you could just have one app with various models (Vote, Project).
Use the standard Django User model if you're not going to extend it, but if your project becomes bigger and more features arise, you might want to at least create your own User model subclassing AbstractUser because it's difficult to change it later on. Even if you just define
class User(AbstractUser):
pass
you'll be prepared for the day you want to add a field to your user model.
No, you don't have a model for each app, you can have multiple models per app. To create relationships, you can use ForeignKey and ManyToManyField. If models are tightly related to each other, they belong in the same app. You can have things split in separate apps for the sake of overview, but be careful then with circular references: you can't import Project in the Vote model and Vote in the Project model.
subclass the AbstractUser.
establish relation between various app Models
from other_app.models import Model1
Class Model2(models.Model):
name = models.CharField(max_length=120)
relation = models.ForeignKey(Model1, on_delete=models.DO_NOTHING)
you can import Model of any app where you need it.

How to perform a model that represents an existing table or a database view?

I'm trying to create a database view from django instead of associate a model from an existing database table. I'm new in django world and i don't know how how can i do this. Anyone have any ideia where to start look to solve this? Maybe this is not possible but can you see any alternative solution?
I understand how to define a model that as no management, by consider managed=False like i found on django docs, but how can i create an customized SQL view in my model class?
something like this:
Class myModel(models.Model):
Object = models.raw("CREATE VIEW foo AS SELECT * FROM table.A")
class Meta:
db_table = 'myview\".\"mymodeltable'
managed = False
With inspectdb management command, you can obtain the models definition from existing tables. To do that, you need to configure your settings.py file to have access to the database you want to work with and then do:
python manage.py inspectdb > models.py
You will see that it also automatically sets the managed=False. From that point, you can start querying its objects with typical objects.all(), objects.filter() and this stuff
Note: Don't forget to add the app with the imported models to the INSTALLED_APPS variable of your settings.py file.
Unfortunately maybe this is the final answer that can be found on DjangoDocs
This is useful if the model represents an existing table or a database view that has been created by some other means.

How to move models in other section in django admin tool?

How to move models to another section in the Django admin site?
In my application module models.py, I have models that are displaying in admin tool in section called "Backend". I want them to display in another section under the name "Requests".
I tried the following
class TransportationRequest(models.Model):
...
class Meta:
app_label = _('Requests')
db_table = 'backend_transportationrequest'
It is works, but now I have issues with South as it is creating migrations to delete all of these models.
Your current issue is that you are trying to change the app_label and db_table, which ends up changing the location of the model data within the database. By default, the database table is generated as [app_label]_[model_name] (backend_transportationrequest in your case), so when you modify both of these, South detects that the model has been removed and created again, even if this isn't actually the case.
The Django migrations framework introduced in 1.7 should have fixed this, so it detects that the model was moved (instead of deleted and created). You may need to fake a migration along the same lines as this with south, which can be done by modifying the two mgirations it generates to not actually delete and create the tables, but rename them.
Django does not currently allow you to easily do this, as the admin site expects that each application that is registered has a unique app_label. You may have luck playing with the label property of your AppConfig, but this is specifically not recommended and has been historically known to cause massive headaches.
One possibility may be to create a clone of your previous model, and only use it to register the app with the Django admin. You would need to create a proxy model with the custom app_label and db_table. If this didn't work (though it should), the other option would be to clone the model as a unmanaged model using the app_label and db_table.

Django ModelAdmin not registered

First, I want to inform that I did check other related questions but their solutions were very simple (improper registration, settings, etc.). This problem is weird in a way that I haven't faced in 3+ years of developing with Django. So here comes:
I have an app that's 90% celery tasks, so it only has two models. They are simple. I have two ModelAdmin classes defined in the admin.py of the app, one for each model. These are simple as well. They are both registered properly. The app is in the INSTALLED_APPS.
All kosher and without any customization of templates, tags or forms, just a plain admin.py:
from myapp.models import (Something, OtherModel)
class SomethingAdmin(admin.ModelAdmin):
# admin config ...
class OtherModelAdmin(admin.ModelAdmin):
pass # Trying anything at this point...
admin.site.register(Something, SomethingAdmin)
admin.site.register(OtherModel, OtherModelAdmin)
So simple it cannot fail, but it does: one of them doesn't show up in the admin. It's simply not registered (404 on manual url access). The other one does show up, and does work properly.
Validation on that invisible admin works because when I add a strange value to its list_display, Django does raise the proper exception (ImproperlyConfigured). So it does reads it, it just fails to register it. If I comment the visible one out, the app is simply removed from the admin (of course, it thinks no modeladmins).
So, in short, one of the ModelAdmins is invisible, while the other one in the same file and with nearly identical configuration, isn't. Any thoughts?
EDIT: Answers to a few suggestions I expect: Yes, the model is working properly (and heavily unit tested), and I have created/saved instances and they are in the db. Yes, I did restart the server. Yes, the computer is plugged in and it's currently on. :)
As it turns out, the problem was in the structure: models was a package, instead of the more usual module. It seems that even if you make the model available at package level (import it in init.py), Django still doesn't know in what app it should be included.
What you need to do is specify the app_label in its Meta class. So the model now becomes:
from django.db import models
class OtherModel(models.Model):
class Meta:
app_label = 'someapp'
# other meta attrs
# Model attrs ...
Odd that it needs to be specified, when the model is available in the usual models.SomeModel namespace, but at least the solution's simple enough.
BTW, as you can guess the other model did include this Meta attr, I just didn't notice it before. LOL.

Do I need to create a separate class in my models.py when using the django.contrib.auth.models import user?

The import statement import the needed parts. but is the "user" class already made when you put that into your installed apps? or do you still need to clarify in models.py in order to make the table in the db? or can someone expand on how to use django users and sessions? I'm looking over the django docs right now and they all just go over how to use the thing once. they never put the code in a syntax where users are going to be the ones using the code through a browser and not you through a python shell.
All installed apps can contribute to the database schema. django.contrib.auth.models contributes, among others, the auth_user table behind the django.contrib.auth.models.User model, therefore you do not have to worry about recreating it unless you have a specific reason to do so.
There's a number of things going on here. As you're aware, Django comes with a number of "contrib" packages that can be used in your app. You "activate" these by putting them into your INSTALLED_APPS.
When you run python manage.py syncdb, Django parse the models.py files of every app in INSTALLED_APPS and creates the associated tables in your database. So, once you have added django.contrib.auth to your INSTALLED_APPS and ran syncdb, the tables for User and Group are there and ready to be used.
Now, if you want to use these models in your other apps, you can import them, as you mention, with something like from django.contrib.auth.models import User. You can then do something like create a ForeignKey, OneToOneField or ManyToManyField on one of your models to the User model. When you do this, no tables are created (with the exception of ManyToManyField; more on that in a bit). The same table is always used for User, just as for any of your own models that you might create relationships between.
ManyToManyFields are slightly different in that an intermediary table is created (often called a "join table") that links both sides of the relationship together. However, this is purely for the purposes of that one particular relationship -- nothing about the actual User table is different or changed in any way.
The point is that one table is created for User and this same table is used to store all Users no matter what context they were created in. You can import User into any and all of your apps, create as many and as varied relationships as you like and nothing really changes as far as User is concerned.
If the table name or something else does not fit in your needs you can always just extend the User model.
from django.contrib.auth.models import User
class Employee(User):
...
Any class extending Model class in models.py contributes to database schema. That means, django search your (and also django core) model.py files and looks for any class that extends Model like:
some models.py
class SomeModel(Model):
...
...
class Otherthing(Model):
...
that is also applies for django core code files. Since all Database tables named using application label and model name, database ables created by django also have that...
For example,
from django.contrib.auth.models import User
If you track file hierarchy django -> contrib -> auth and open models.py file, you will see related model. Ther are also other Model classes in here, like Permission and Group models.
Since these models are under auth application, database tables are auth_user, auth_perission and auth_group
When you run manage.py syncdb command for the first time, django will create these tables...

Categories

Resources