Django Migrate Change of App Name (active project) - python

So... I've done a lot of research on this... there are answers, but not complete or appropriate answers. I have an in-use and in-production django "project" in which the "main" application is called "pages" ... for reasonably dumb reasons. My problem is now to add mezzanine ... which has a sub-module mezzanine.pages (seems to be required .... but I'm pretty sure I need it).
mezzanine.pages apparently conflicts with "pages" ...
Now ... my pages contains a slew of non-trivial models including one that extends user (One-to-One ref), and many references to other app's tables (fortunately only outbound, ForeignKey). It also has management/commands and about 20 migrations of it's own history.
I gather I either have to changes pages to mypages or is there another route (seemingly changing mezzanine.pages seems wrong-headed).
for reference, The project is on Django 1.8 right now, so the preferred answer includes migrations.

I've worked on this since I posted it, and the real answer is what I've synthesized from multiple sources (including other stack exchange posts).
So... Everything changed in Django before I started using it. After 1.7, the 'migrations' bit was internalized and posts including the word "South" are about how the world was before 1.7. Further, the complication in my case dealt with the issue of migrations in that the project was already active and had real data in production.
There were some posts including a GITHub chunk of code that talked about migrating tables from one App to another App. This is inherently part of the process, but several posts noted that to do this as a "migration" you needed the Migration.py to be in another App. Maybe even an App created for the purpose.
In-the-end, I decided to approach the problem by changing the label in the Application class of apps.py in the application in question. In my case, I am changing "pages" to "phpages" but the directory name of my app is still pages. This works for me because the mezzanine app's "pages" sub-App is back in the python library and not a conflict in the filesystem. If this is not your situation, you can solve it with another use of label.
So... Step-by-step, my procedure to rename pages to phpages.
Create apps.py in the pages sub-directory. In it put:
class PagesConfig(AppConfig):
name = "pages"
label = "phpages"
verbose_name = "Purple Hat Pages"
Key among these is label which is going to change things.
In __init__.py in the pages sub-directory, put default_app_config = "pages.apps.PagesConfig"
In your settings.py change the INSTALLED_APPS entry for your app to 'pages.apps.PagesConfig', ...
All of your migrations need to be edited in this step. In the dependencies list, you'll need to change 'pages' to 'phpages'. In the ForeignKeys you'll need to also change 'pages.Something' to 'phpages.Something' for every something in every migration file. Find these under pages/mitrations/nnnn_*.py
If you refer to foreign keys in other modules by from pages.models import Something and then use ForeignKey(Something), you're good for this stop. If you use ForeignKey('pages.Something') then you need to change those references to ForeignKey('phpages.Something'). I would assume other like-references are the same.
For the next 4 steps (7, 8, 9 and 10), I built pagestophpages.sql and added it to the pages sub-directory. It's not a standard django thing, but each test copy and each production copy of the database was going to need the same set of steps.
UPDATE django_contecnt_type SET app_label='phpages' WHERE app_label='pages';
UPDATE django_migrations SET app='phpages' WHERE app='pages';
Now... in your database (my is PostgreSQL) there will be a bunch of tables that start with "pages". You need to list all of these. In PostgreSQL, in addition to tables, there will be sequences for each AutoField. For each table construct ALTER TABLE pages_something RENAME TO phpages_something; For each sequence ALTER SEQUENCE pages_something_id_seq RENAME TO phpages_something_id_seq;
You should probably backup the database. You may need to try this a few times. Run your SQL script through your database shell. Note that all other changes can be propagated by source code control (git, svn, etc). This last step must be run on each and every database.
Obviously, you need to change pages and phpages to your stuff. You may have more than one table with one auto field and it may not be named something.
Another thing of note, in terms of process, is that this is probably a hard point in your development where everything needs be in sync. Given that we're playing with editing migrations and changing names, you need a hard stop in development so that everything that's going to be changed (dev box, test box, staging box, production box ... and all of their databases) is at the same revision and schema. YMMV.
This is also solving the problem by using the label field of class Application. I choose this method in deference to changing the directory name because it involved fewer changes. I chose not to change the name field because that did not work for me. YMMV.
I must say that I'm a little disappointed that myapp/pages conflicts with mezzanine.pages. It looks like some of the reasons are due to the pages slug being used in the database table name (and off top of my head, I don't see a good solution there). What I don't see that would make sense is the equivalent to "from mezzanine import pages as mpages" or somesuch. The ability to alias imported apps (not talking about apps in my own file tree). I think this might be possible if I sucked in the app into my own file tree --- but this doesn't seem to be a sanctioned act, either.

Related

How to combine 2 django projects

I have 2 apps which i would like to combine, the first one is a login & register system and the next one is a file upload system how would i go by combining them?
This is a very specialized question that depends heavily on the code contained within them. Assuming they are set up as two separate forms in their own views, you may be able to put two separate forms on the same page but without seeing the code, screenshots, design plans or anything of the like, this is a very difficult question to answer.
I would like to have commented this instead, but I don't have the rep. Sorry for not actually answer the question.
There are many ways to do this and it would all depend on how your project is setup. Normally when you create a project in django you are forced to create an app, this is for modularity, the idea is to be able to have the apps be self contained entities, so in your case, you may want to move the app itself (not the project) from the upload system to your main login & register app, so just move / copy the "app" folder over to your other project, then you will also need to copy the settings and move them over. You also need to update the urls.py in your main app to include the urls from your second app.
Anyways this should give you some hints on how you could do this.

django structure for multiple modules

I'm very new to django and python as well. I want to try out a project written in django.
Let say the project have 3 modules
User
CRUD
Forgot password
login
Booking
CRUD
Search
Default (basically is for web users to view)
Home page
about us
All these have different business logic for the same entity.
Should I create 3 apps for this? If 3 different apps, then the table name is all different as it will automatic add a prefix for table name.
Any suggestion?
There's really no correct answer to this. In general, the way in which you break down any programming task into 'modules' is very much a matter of personal taste.
My own view on the subject is to start with a single module, and only break it into smaller modules when it becomes 'necessary', e.g. when a single module becomes excessively large.
With respect to the apps, if all the apps share the same database tables, you'll probably find it easier to do everything in a single app. I think using multiple Django apps is only really necessary when you want to share the same app between multiple projects.
I agree in #aya answer and I also supported your structure for multiple modules. In my project, I created 18 apps. Each app perform different rules:
1. accounts
- login
- forgot password
- register
- profile
2. common
//in here all the common function use by different apps
3. front
- home
- testimonial
4. guides
//tutorials
And lots more apps...
I arrange this way so that it will be easy to trace, debug, and find the codes. If your problem is the name of table you can set the class Meta of db_table.
I am relatively new to Django and Python myself too. In practice, try to have your Django apps do one thing and do it well. If you find that an app is becoming more and more complex, it may be worth splitting this out into multiple apps.
I would not worry about the DB tablename as Django handles the DB interaction for you. If you name your apps and models well, your code should be fairly self documenting.
I have recently learnt a lot of "best practices" in how to setup and layout Django projects from the ebook 2 Scoops of Django. I am not affiliated with them in any way, but have just learnt a lot from it.
Also, definitely run through the Django tutorial if you haven't already.
Hope this has helped!
Focus on making your apps reusable. This way you will save significant number of time in your next project. Good article about it is available at the Django's website.
If you have closely integrated modules or depending on each other, then there's no real benefit of having them in separate apps, because you won't ever use them separately. Organizing in separate Python modules will be just fine.
Also do not think about "how will my tables be named" when you consider project organization. Tables can be easily renamed while bad design will make you trouble as the project will grow.

Django and MVC(MVT) layout

Im coming from using other MVC based frameworks, and going into Django, it seems a little awkward to what im used to. For example, in other MVC based frameworks. my layout might be like so:
root:
- config (houses the config files (like settings), url.conf, db connections, etc.)
- controllers (houses the main logic of each section of the site. The middle ground between views and models)
- models (handles all the data to be validated and anything that interacts with the database. declares the DB structure. each model a class, each attribute a db field. in django, a template?)
- views (the html displayed to the end user, put together by the controllers)
- tests (all the tests)
- plugins (3rd party apps you install into yours.)
- uploads (user uploaded files)
- public_html (the actual public facing files)
-\ css|js|img (the various static file types for page manipulation)
-\ index.html
That is what im used to, and it seems like django does things very differently. Where before if I had a poll app i would have:
controllers/PollController.py
models/Poll.py
views/poll/index.py
and that would create the poll table in the db. But in Django, how would I do this? Is this an acceptable layout? From what I have read, the above would be more like this:
root:
- project (this would be the main app, and what glues everything together)
--/ settings.py
--/ urls.py
--/ templates/
- apps
-/ Poll
--/ models.py (i would have no Poll.py model, so it would all go in here)
--/ urls.py (any url.conf specific to this model would go in here)
--/ templates/ (the various views for this app)
while this does makes sense in some ways, it just feel alien to me. Is there any benefit to this type of layout over a traditional mvc layout described in the first example? Is there another preferred layout beyond this? The purpose of this 'project' is that the core will be a basic framework for my own use and I have a few different 'apps' that i will create for each use of this framework. in the old version each application would just extend the main one by being a plugin in that directory.
As a background note, most of my experience is in php and the various frameworks from that worls (cakephp, yii, mostly), if that makes a difference. This will be my first main project in python/django. i just want to get it right.
The biggest benefit is that apps are modularized. You can remove your Poll application by deleting one directory instead of hunting through several directories deleting each piece. The flip side is if you found a Poll application somewhere that you wanted to use you can just drop in the one folder and you're good to go.
If you approach the idea of a site being a conglomeration of several individual and mostly distinct "apps" with some glue to hold them together then this organization makes much more sense.
Is there any benefit to this type of layout over a traditional mvc layout described in the first example?
Yes.
What you appear to be calling "Traditional MVC" is just another framework. It's not magically better or more right. It's just different.
Is there another preferred layout beyond this?
There are probably hundreds of ways to do this. Django chose one that fits nicely with Python and web applications.
i just want to get it right.
Then do this.
Discard your preconceptions left over from other things you've done.
Start fresh and empty with Django like a complete beginner.
After you've learned your 6th framework, you can then (and only then) compare and contrast the six frameworks you've learned. Until you've learned six, each one has to be taken as new, complete, different and unique.
Don't compare and contrast yet.
Just take Django as Django and do things the Django way.
(For more metaphorical advice, read about the music of Django Reinhardt; he had a unique view and a unique approach to the guitar.)
Notes
root # doesn't mean anything
config -- Doesn't exist.
controllers -- Doesn't exist.
models -- A Python module with the class definitions for the persistent objects. Maps to RDBMS schema. Can have model-specific tests.
views -- A Python module with view functions that respond to requests and create responses.
test -- A Python module with View-specific and template-specific tests.
plugins -- Doesn't exist.
uploads -- Runtime, not development of the application.
public_html -- Does not exist.
css|js|img -- Static "Media" files. Runtime, not development.
index.html -- Does not exist.
Stuff you omitted
templates -- your HTML template pages, used by the view functions.
admin -- admin bindings for the default admin site. Relies on modules and forms.
forms -- form definitions; these are classes that produce forms used for input validation.
urls -- mappings from URL paths to view functions.
settings -- module with default database configuration, middleware, etc.

How to make some Django settings accessible by staff?

In Django, settings are stored in a file, settings.py. This file is part of the code, and goes into the repository. It is only the developers who deal with this file. The admin deals with the models, the data in the database. This is the data that the non-development staff edits, and the site visitors see rendered in templates.
The thing is, our site, and many others, have lots of settings options that should be edited by non-developer staff. We're talking about stand-alone site-wide constants that really have no place in the database. Putting them in the database will result in numerous pointless queries. Caching could alleviate that, but that seems unnecessarily complex to handle what can be done with a single line in the settings.py file.
I did notice this dbsettings app, but it is old and unmaintained. I also noticed that the django e-commerce app, Satchmo, includes a use-case specific fork of this dbsettings app. We could build something similar into our site, an app that stores some settings as key/value pairs in a single database table, but it just really seems like the wrong approach. Why put something in the DB that doesn't belong there just to make it more easily editable by non-developers?
We have a list of site-wide settings on our Django site that we want to be editable by non-developer administrators. What is the best way of going about this?
Something like dbsettings (as you mentioned) seems like the way to go. From the reasons for existence for that project:
Not all settings belong in
settings.py, as it has some
particular limitations:
Settings are project-wide. This not only requires apps to clutter up
settings.py, but also increases the chances of naming
conflicts.
Settings are constant throughout an instance of Django. They cannot be
changed without restarting the application.
Settings require a programmer in order to be changed. This is true even
if the setting has no functional impact on anything else.
If dbsettings doesn't work for you, then implement your own, or fork it. It doesn't seem like it'd be too arduous.
I'm actually a big fan of dbsettings, and keep meaning to publish my fork that patches it to work with Django 1.1 (not actually a big change). Looks like someone has updated it already.
However, you're probably right that this is overkill for what you need. One thing I've done before is to add a line to the end of settings.py that imports and parses a YAML file. YAML is a simple markup language, which at its most basic is just KEY: VALUE ...
CONSTANT1: MyValue
CONSTANT2: Anothervalue
If you put this somewhere editors can access it, then at the end of settings.py you just do:
import yaml
try:
globals().update(yaml.load(open('/path/to/my/yaml/file.yml')))
except:
pass
You'll need the Python YAML library to parse the YML file.
The downside to this approach is that you'll need to restart Apache to get it to pick up the changes.
Edited to add It wouldn't be particularly difficult to build a front end which could edit this file, and provide a button which runs a script to restart Apache.
If you must avoid server restarts then a logical place for the settings is the database as Dominic and Daniel said, but you'll need to invalidate cached settings object every time it is updated.
Looks like it's possible to re-set values in the cache with Django's low level cache API. All you want should be achievable with these calls:
cache.set('settings', local_settings)
cache.add('settings', local_settings)
local_settings = cache.get('settings')
cache.delete('settings')
How about putting a sitesettings.py (or whatever) somewhere that your admins can access, then in settings.py do
from sitesettings import *
That seems good and simple, but I may have misunderstood or oversimplified your problem :)
models.py
class Setting(models.Model):
"""Global settings for app"""
name = models.CharField(max_length=100, null=False, blank=False)
value = models.CharField(max_length=100, null=False, blank=False)
def __str__(self):
return self.name
admin.py
from YOUR_APP.models import Setting
class SettingAdmin(admin.ModelAdmin):
list_display = (
'name',
'value',
)
admin.site.register(Setting, SettingAdmin)
extras.py
#register.filter
def get_setting(name):
setting = Setting.objects.get(name=name)
return setting.value
template.html
{% if 'setting_name'|get_setting == 'true' %}
Display your Feature
{% endif %}
Django Packages has a page that lists packages that provide such functionality - most query the database and then use caching to minimize hits on the DB.
I found Django Dynamic Preferences to be of particular interest due to the fine-grained control it gives you over the configuration.

How do you manage your Django applications?

I just wanted to try to build a project with django. Therefore I have a (basic) question on how to manage such a project. Since I cannot find any guidelines or so on how to split a project into applications.
Let's take a kind of SO as an example. Which applications would you use?
I'd say there should be the applications "users" and "questions". But what if there was a topic system with static articles, too. Maybe they also could receive votes.
How to build the apps structure then? One app for "questions", "votes" and "topics" or just one app "content"?
I have no idea what to do. Maybe it's because I know not very much about Django yet, but I'm interested either...
There aren't hard-and-fast rules, but I would say it's better to err on the side of more specialized applications. Ideally an application should handle just one functional concern: i.e. "tagging" or "commenting" or "auth/auth" or "posts." This type of design will also help you reuse available open source applications instead of reinventing the wheel (i.e. Django comes with auth and comments apps, django-tagging or django-taggable can almost certainly do what you need, etc).
Generic foreign keys can help you decouple applications such as tagging or commenting that might be applied to models from several other applications.
You should try and separate the project in as much applications as possible. For most projects an application will not contain more than 5 models. For example a project like SO would have separate applications for UsersProfiles, Questions, Tags (there's a ready one in django for this), etc. If there was a system with static pages that'd be a separate application too (there are ready ones for this purpose). You should also try and make your applications as generic as possible, so you may reuse them in other projects. There's a good presentation on reusable apps.
Just like any set of dependencies... try to find the most useful stand-alone aspects of the project and make those stand-alone apps. Other Django Apps will have higher level functionality, and reuse the parts of the lowest level apps that you have set up.
In my project, I have a calendar app with its own Event object in its models. I also have a carpool database set up, and for the departure time and the duration I use the calendar's Event object right in my RideShare tables. The carpooling database is calendar-aware, and gets all the nice .ics export and calendar views from the calendar app for 'free.'
There are some tricks to getting the Apps reusable, like naming the templates directory: project/app2/templates/app2/index.html. This lets you refer to app2/index.html from any other app, and get the right template. I picked that one up looking at the built-in reusable apps in Django itself. Pinax is a bit of a monster size-wise but it also demonstrates a nice reusable App structure.
If in doubt, forget about reusable apps for now. Put all your messages and polls in one app and get through one rev. You'll discover during the process what steps feel unnecessary, and could be broken out as something stand-alone in the future.
A good question to ask yourself when deciding whether or not to write an app is "could I use this in another project?". If you think you could, then consider what it would take to make the application as independent as possible; How can you reduce the dependancies so that the app doesn't rely on anything specific to a particular project.
Some of the ways you can do this are:
Giving each app its own urls.py
Allowing model types to be passed in as parameters rather than explicitly declaring what models are used in your views. Generic views use this principle.
Make your templates easily overridden by having some sort of template_name parameter passed in your urls.py
Make sure you can do reverse url lookups with your objects and views. This means naming your views in the urls.py and creating get_absolute_url methods on your models.
In some cases like Tagging, GenericForeignKeys can be used to associate a model in your app to any other model, regardless of whether it has ForeignKeys "looking back" at it.
I'll tell you how I am approaching such question: I usually sit with a sheet of paper and draw the boxes (functionalities) and arrows (interdependencies between functionalities). I am sure there are methodologies or other things that could help you, but my approach usually works for me (YMMV, of course).
Knowing what a site is supposed to be is basic, though. ;)

Categories