686 """ project.</p>""" |
685 """ project.</p>""" |
687 )) |
686 )) |
688 self.showMigrationsPlanAct.triggered.connect(self.__showMigrationsPlan) |
687 self.showMigrationsPlanAct.triggered.connect(self.__showMigrationsPlan) |
689 self.actions.append(self.showMigrationsPlanAct) |
688 self.actions.append(self.showMigrationsPlanAct) |
690 |
689 |
691 # TODO: makemigrations |
690 self.migrateAllAct = E5Action( |
692 # TODO: migrate |
691 self.tr('Apply All Migrations'), |
|
692 self.tr('&Apply All Migrations'), |
|
693 0, 0, |
|
694 self, 'django_migration_apply_all') |
|
695 self.migrateAllAct.setStatusTip(self.tr( |
|
696 'Apply all available migrations')) |
|
697 self.migrateAllAct.setWhatsThis(self.tr( |
|
698 """<b>Apply All Migrations</b>""" |
|
699 """<p>This applies all migrations of the Django project.</p>""" |
|
700 )) |
|
701 self.migrateAllAct.triggered.connect(self.__applyAllMigrations) |
|
702 self.actions.append(self.migrateAllAct) |
|
703 |
|
704 self.migrateSelectedAct = E5Action( |
|
705 self.tr('Apply Selected Migrations'), |
|
706 self.tr('Apply Selected Migrations'), |
|
707 0, 0, |
|
708 self, 'django_migration_apply_selected') |
|
709 self.migrateSelectedAct.setStatusTip(self.tr( |
|
710 'Apply selected migrations')) |
|
711 self.migrateSelectedAct.setWhatsThis(self.tr( |
|
712 """<b>Apply Selected Migrations</b>""" |
|
713 """<p>This applies selected migrations of the Django""" |
|
714 """ project.</p>""" |
|
715 )) |
|
716 self.migrateSelectedAct.triggered.connect( |
|
717 self.__applySelectedMigrations) |
|
718 self.actions.append(self.migrateSelectedAct) |
|
719 |
|
720 self.unmigrateAct = E5Action( |
|
721 self.tr('Unapply Migrations'), |
|
722 self.tr('&Unapply Migrations'), |
|
723 0, 0, |
|
724 self, 'django_migration_unapply') |
|
725 self.unmigrateAct.setStatusTip(self.tr( |
|
726 'Unapply all migrations for an app')) |
|
727 self.unmigrateAct.setWhatsThis(self.tr( |
|
728 """<b>Unapply Migrations</b>""" |
|
729 """<p>This unapplies all migrations for an app of the Django""" |
|
730 """ project.</p>""" |
|
731 )) |
|
732 self.unmigrateAct.triggered.connect(self.__unapplyMigrations) |
|
733 self.actions.append(self.unmigrateAct) |
|
734 |
|
735 self.makeMigrationsAct = E5Action( |
|
736 self.tr('Make Migrations'), |
|
737 self.tr('&Make Migrations'), |
|
738 0, 0, |
|
739 self, 'django_migration_make') |
|
740 self.makeMigrationsAct.setStatusTip(self.tr( |
|
741 'Generate migrations for the project')) |
|
742 self.makeMigrationsAct.setWhatsThis(self.tr( |
|
743 """<b>Make Migrations</b>""" |
|
744 """<p>This generates migrations for the Django project.</p>""" |
|
745 )) |
|
746 self.makeMigrationsAct.triggered.connect(self.__makeMigrations) |
|
747 self.actions.append(self.makeMigrationsAct) |
|
748 |
693 # TODO: squashmigrations |
749 # TODO: squashmigrations |
|
750 |
|
751 # TODO: sqlmigrate |
694 |
752 |
695 def initMenu(self): |
753 def initMenu(self): |
696 """ |
754 """ |
697 Public method to initialize the Django menu. |
755 Public method to initialize the Django menu. |
698 |
756 |
2095 except DjangoNoSiteSelectedException: |
2159 except DjangoNoSiteSelectedException: |
2096 return |
2160 return |
2097 |
2161 |
2098 from .DjangoMigrationsListDialog import DjangoMigrationsListDialog |
2162 from .DjangoMigrationsListDialog import DjangoMigrationsListDialog |
2099 self.__migrationsPlanDialog = DjangoMigrationsListDialog( |
2163 self.__migrationsPlanDialog = DjangoMigrationsListDialog( |
2100 DjangoMigrationsListDialog.MigrationsPlanMode, self.__ui) |
2164 DjangoMigrationsListDialog.MigrationsPlanMode, self, self.__ui) |
2101 self.__migrationsPlanDialog.show() |
2165 self.__migrationsPlanDialog.show() |
2102 self.__migrationsPlanDialog.start(self.__getPythonExecutable(), path) |
2166 self.__migrationsPlanDialog.start(self.__getPythonExecutable(), path) |
|
2167 |
|
2168 def __applyAllMigrations(self): |
|
2169 """ |
|
2170 Public slot to apply all migrations. |
|
2171 """ |
|
2172 self.applyMigrations() |
|
2173 |
|
2174 def __applySelectedMigrations(self): |
|
2175 """ |
|
2176 Public slot to apply selected migrations of a selected app. |
|
2177 """ |
|
2178 migrations = self.__getMigrations() |
|
2179 if not migrations: |
|
2180 E5MessageBox.information( |
|
2181 None, |
|
2182 self.tr("Apply Selected Migrations"), |
|
2183 self.tr("""No migrations available.""")) |
|
2184 return |
|
2185 |
|
2186 from .DjangoMigrationSelectionDialog import \ |
|
2187 DjangoMigrationSelectionDialog |
|
2188 dlg = DjangoMigrationSelectionDialog(migrations) |
|
2189 if dlg.exec_() == QDialog.Accepted: |
|
2190 app, migration = dlg.getData() |
|
2191 self.applyMigrations(app=app, migration=migration) |
|
2192 |
|
2193 def applyMigrations(self, app=None, migration=None): |
|
2194 """ |
|
2195 Public slot to apply migrations. |
|
2196 |
|
2197 @param app name of an application to apply migrations for |
|
2198 @type str |
|
2199 @param migration name of a migration to update to |
|
2200 @type str |
|
2201 """ |
|
2202 if migration == "zero": |
|
2203 title = self.tr("Unapply Migrations") |
|
2204 else: |
|
2205 title = self.tr("Apply Migrations") |
|
2206 |
|
2207 try: |
|
2208 path = self.__sitePath() |
|
2209 except DjangoNoSiteSelectedException: |
|
2210 return |
|
2211 |
|
2212 args = [] |
|
2213 args.append(self.__getPythonExecutable()) |
|
2214 args.append("manage.py") |
|
2215 args.append("migrate") |
|
2216 args.append("--noinput") |
|
2217 if app: |
|
2218 args.append(app) |
|
2219 if migration: |
|
2220 args.append(migration) |
|
2221 |
|
2222 dia = DjangoDialog(title) |
|
2223 res = dia.startProcess(args, path) |
|
2224 if res: |
|
2225 dia.exec_() |
|
2226 |
|
2227 def __unapplyMigrations(self): |
|
2228 """ |
|
2229 Private slot to un-apply all migrations of an application. |
|
2230 """ |
|
2231 apps = list(sorted(self.__getMigrations().keys())) |
|
2232 if not apps: |
|
2233 E5MessageBox.information( |
|
2234 None, |
|
2235 self.tr("Unapply Migrations"), |
|
2236 self.tr("""No migrations available.""")) |
|
2237 return |
|
2238 |
|
2239 app, ok = QInputDialog.getItem( |
|
2240 None, |
|
2241 self.tr("Unapply Migrations"), |
|
2242 self.tr("Select an application:"), |
|
2243 [""] + apps, |
|
2244 0, False) |
|
2245 if ok and app: |
|
2246 self.applyMigrations(app=app, migration="zero") |
|
2247 |
|
2248 def __getMigrations(self): |
|
2249 """ |
|
2250 Private method to get the available migrations. |
|
2251 |
|
2252 @return dictionary containing the available migrations |
|
2253 @rtype dict with app name as key (str) and list of tuples of |
|
2254 applied indication (bool) and migration name (str) as value |
|
2255 """ |
|
2256 try: |
|
2257 path = self.__sitePath() |
|
2258 except DjangoNoSiteSelectedException: |
|
2259 return {} |
|
2260 |
|
2261 args = [] |
|
2262 args.append("manage.py") |
|
2263 args.append("showmigrations") |
|
2264 args.append("--list") |
|
2265 |
|
2266 migrations = {} |
|
2267 proc = QProcess() |
|
2268 if path: |
|
2269 proc.setWorkingDirectory(path) |
|
2270 proc.start(self.__getPythonExecutable(), args) |
|
2271 if proc.waitForStarted(): |
|
2272 if proc.waitForFinished(): |
|
2273 output = str(proc.readAllStandardOutput(), |
|
2274 Preferences.getSystem("IOEncoding"), 'replace') |
|
2275 if output: |
|
2276 recentApp = "" |
|
2277 for line in output.splitlines(): |
|
2278 if not line.startswith(" "): |
|
2279 # application name |
|
2280 recentApp = line.strip() |
|
2281 migrations[recentApp] = [] |
|
2282 else: |
|
2283 # migration name |
|
2284 line = line.strip() |
|
2285 applied = line[1] != " " |
|
2286 name = line[3:].strip() |
|
2287 if recentApp: |
|
2288 migrations[recentApp].append((applied, name)) |
|
2289 return migrations |
|
2290 |
|
2291 def __makeMigrations(self): |
|
2292 """ |
|
2293 Private slot to generate migrations for the Django project. |
|
2294 """ |
|
2295 from .DjangoMakeMigrationsDialog import DjangoMakeMigrationsDialog |
|
2296 dlg = DjangoMakeMigrationsDialog(self.getRecentApplications()) |
|
2297 if dlg.exec_() == QDialog.Accepted: |
|
2298 apps, migration, dryRun = dlg.getData() |
|
2299 if apps: |
|
2300 self.setMostRecentApplication(apps) |
|
2301 apps = apps.split() |
|
2302 self.makeMigrations(apps, migration, dryRun) |
|
2303 |
|
2304 def makeMigrations(self, apps, migration=None, dryRun=False): |
|
2305 """ |
|
2306 Public method to generate migrations. |
|
2307 |
|
2308 @param apps list of application names to generate migrations for |
|
2309 @type list of str |
|
2310 @param migration name of the migration to generate |
|
2311 @type str |
|
2312 @param dryRun flag indicating a dry run |
|
2313 @type bool |
|
2314 """ |
|
2315 title = self.tr("Make Migrations") |
|
2316 |
|
2317 try: |
|
2318 path = self.__sitePath() |
|
2319 except DjangoNoSiteSelectedException: |
|
2320 return |
|
2321 |
|
2322 args = [] |
|
2323 args.append(self.__getPythonExecutable()) |
|
2324 args.append("manage.py") |
|
2325 args.append("makemigrations") |
|
2326 args.append("--noinput") |
|
2327 if migration: |
|
2328 args.append("--name") |
|
2329 args.append(migration.replace(" ", "_")) |
|
2330 if dryRun: |
|
2331 args.append("--dry-run") |
|
2332 if apps: |
|
2333 args += apps |
|
2334 |
|
2335 dia = DjangoDialog(title) |
|
2336 res = dia.startProcess(args, path) |
|
2337 if res: |
|
2338 dia.exec_() |
2103 |
2339 |
2104 ################################################################## |
2340 ################################################################## |
2105 ## slots below implement some tool functions |
2341 ## slots below implement some tool functions |
2106 ################################################################## |
2342 ################################################################## |
2107 |
2343 |