Django cheat sheet

Creating a base project: django-admin startproject projectname

New app within existing project: python3 manage.py startapp appname

You’ll want to add the appname to the end of the list of INSTALLED_APPS in projectname/settings.py

Django uses Model View Controller pattern – URL Pattern maps to Views, which return HTML and can make use of Models and Templates.

https://docs.djangoproject.com/en/4.0/topics/db/models/

Migrations – generate scripts to change our existing database structure as we make updates & changes. Used when you add a new model, or add, remove, or change fields on an existing model.

Migration commands:

python3 manage.py makemigrations

Generates files for later use using current model fields & database tables. Creates numbered files in migrations folder. (if made but hasn’t been run yet, it’s unapplied; common error so use migrate command below)

python3 manage.py showmigrations

python3 manage.py migrate <appname> <number>

appname and number are OPTIONAL, and without them it runs all migrations that haven’t yet been run. Using them lets you run migrations in a specific app up to a specific number.

python3 manage.py createsuperuser

Use HTML templates for pages. Templates can inherit from other templates, and can have code (including javascript files) injected into them.

Working with Docker

Reference here

First – what is docker?

The gist is that it’s somewhat of a replacement for clunky linux virtual machines that you might use just for programming / software development. There are two main parts – Containers and Images.

A Container is like a tiny, minimalistic virtual machine. It creates a small space to run separately from everything else in your system. And you don’t need to set aside a portion of your hard-drive or bother with installing an operating system. It’s the “thing” you run your app in.

Why is this helpful? Besides saving one the trouble of setting up a virtual machine, the fact that it creates an entirely isolated system means that you can know whether or not your application includes everything it needs to run on systems that aren’t yours. I definitely had problems way back of “but it works on my computer” only to realize that some small dependency had to be installed on the recipient’s end. Though I think that’s much less common with dependency files and systems that automatically install those dependencies before running the app, this will still make it very clear whether you have set up those files correctly or not (as I know some languages, like Python, will install packages/modules system-wide if you don’t specify not to).

Images are the “instructions” of how to set up the container. They seem to be a common “starting point” for your application from which all separately-running instances are copies.

First you need to build the image using:

docker build –tag image-name path-to-image

(If you are already in the folder you want to run in docker, you can just use . instead of a full path as usual)

You need to have your docker file set up first, but running an image for the first time seems to work like this:

docker run -p clientPort:ServerPort –name process-name -d directory-name 

(if you do not name it, it will create a random name for you)

You can use ‘docker ps’ to see currently running containers, and add the -a flag if you want to see containers that aren’t running as well. You can use ‘docker stop’ to stop it and ‘docker start’ to start the same one back up without having to specify port again; it’ll go run on the same port as before. It seems like you don’t use docker start on a container that doesn’t exist; you use run first to create it. If you want to delete one, you have to find the name using ‘docker ps -a’ (or just know the name if you named it yourself) and use ‘docker rm name’.

Testing in Flutter

Unit tests:

You can use the flutter_test library. Cheat sheet below

  • group((String) description, () {}) – function allows you to create a group of tests. The tests go inside the curly braces, of course.
  • test((String) description, () {}) – inside the group body, used to run a synchronous test
  • testWidget((String) description, () async {}) – also inside the group body, used to run an async test. (I believe it doesn’t *have* to run an async test, but it’s useful for that)
  • expect(actual, matcher) – use inside of a test. You can have the matcher be a constant like findsOneWidget (since both actual and matcher are dynamic)
  • WidgetTester – class that handles widgets in the testing environment. Can use pumpWidget or pumpAndSettle to render the widgets in the test environment. This can let you test if the UI is displaying correctly (eg if you add something to a displayed list, does it show up?)

Integration Tests:

Misc things learned:

Bloc Pattern Todo List

General process of implementing the bloc pattern:

  1. Model for Todo Items (the data we’ll be using)
  2. States representing the loading process for the To-do list; are they loading, loaded, or unable to be loaded?
  3. Events representing the operations done on the To-do list; these are for each of the operations we are going to be doing in the app.
  4. The Bloc class; extending a Bloc, it takes in the Events from step 3 and maps them to the proper states in step 4.

The Equatable package and class make it easier to use the == and hashCode functions without having to manually override them yourself.

You can have multiple blocs, each handling different aspects of the app (eg. TodosBloc handles CRUD with the todos, FilteredTodosBloc controls which of those todos we can see based on our filtering criteria).

A BlocDelegate tracks the events, transitions, and errors among the various blocs.

Here is an article describing some operators for dart. It helps a lot to understand the code in the tutorial.

What not to commit in Dart (but mostly applies to flutter too). Long story short, just commit your lib and pubspec.yaml.

CRUD with PostgreSQL in Flutter

Using this tutorial. Had to install dart to get the pub command.

Tutorial on customizing zsh (in case I want to do that later).

Added the directory where pub installs all of its executables to PATH (in ~/.zshrc )

You can then refresh the terminal to use the newly changed config file without closing and reopening it with “source $HOME/.zshrc”

“aqueduct serve” crashed with an IsolateSpawnException. Running “flutter pub upgrade” did not fix it. What *did* fix it is navigating into the aqueduct project folder. It was having trouble finding my pubspec.yaml file.

If you get “Error: Getter not found: ‘defaultType’. ” with aqueduct serve, try “pub run aqueduct serve” instead.

It seems like any files that you want to import into channel.dart need to be located somewhere in or under the lib folder. Using ‘..’ in your import path just gets you ‘package:’ instead of the project folder.

Notice we are using @Bind.path('id') int id as the input parameter. This is to declare our input parameter which is path('id') and bind it as argument of type integer for the method getHeroByID.

With that, we can pull the entire list or a single entry. Next is to make it work with Postgres instead of a hard-coded list.

I seem to have successfully applied the aqueduct migration file, but when I run “aqueduct serve” it is still pulling from the old list of heroes instead of the newly generated one. There’s probably a step missing from the tutorial.

Thanks to this tutorial series on youtube I was able to figure out what was missing. I needed a data model for the data, and code to actually fetch the data from the database instead of from the hardcoded list. It seems that the Flutter tutorial left that part out entirely, though thankfully their GitHub included the correct code.

Starting the database:

pg_ctl -D /usr/local/var/postgres start
psql postgres
postgres-# \c database-name
postgres=# \q
aqueduct serve

Implementing the commands was easy enough, except for put. The problem wasn’t with put itself; but the application used to test in the tutorial doesn’t send a proper put request. Using Postman instead fixed that issue.

Implementing everything in a flutter app ran into issues when testing on the android emulator. Localhost on the emulator just tries to go to the emulated machine. Solved the issue by changing the url used in the app to the actual ip address of the machine, and setting the android emulator’s proxy to the same (with the port of the aqueduct server). Make sure to actually close and reopen the emulator after doing this! A hot reload or restart is not good enough.

Additionally, since the id (primary key) used for put is in the path, you do not need to include it in the body. (in fact, since it’s a managed primary key, you should *not* include it in the body, as you’ll just confuse the database).

When updating, the change doesn’t display immediately. Sometimes you have to tap on an item and back out to re-render the list, and only then can you see the change. I’d like to figure out a way to fix that; either delay the rendering of the list screen after sending a request, or notify the screen when the request returns that it should re-render.

Postgres Exercises for later!

Boring Show Episode 2 Notes

Basic Testing Tutorial here.

Flutter test library documentation here.

Tester.pump() runs one frame of the app and then stops.

Tester.pumpAndSettle() runs until the queued events are all done.

You can do find.byIcon() or find.byType() (and likely a lot of other useful things too).

For converting JSON, quick and easy way is to use dart:convert (built-in).

Factory: function that looks like a constructor. Does its stuff, calls actual constructor (or fetches the already-existing object you want), returns value. Can be used for singletons etc.

Don’t need ‘new’ keyword in Dart 2.0

Built Value library: generates (source) code on your behalf. (Look into flutter source gen). Good for things where the structure of the data might be unknown or might change on you (eg. JSON pulled from a constantly-changing API)

Built Value = immutable data class. You hand it data to populate itself with and after populating, nothing can mess with it.

Saving Data to the Cloud with Firebase

I am following this tutorial.

Here’s another tutorial on uploading images, video and audio. Not exactly what I need but might be useful later.

Had a bit of trouble finding the bundle identifier for iOS. Found it in ios/Runner.xcodeproj/project.pbxproj . The generated file goes in the ios/Runner folder. The pod file, on the other hand, is just in the iOS folder.

Had a lot of errors with Pod Install;

CDN: trunk URL couldn't be downloaded:https://raw.githubusercontent.com/CocoaPods/Specs/master/Specs/0/3/5/Firebase/6.9.0/Firebase.podspec.json, error: Failed to open TCP connection to raw.githubusercontent.com:443 (Connection refused - connect(2) for "raw.githubusercontent.com" port 443)

Trying again a few times the next day fixed it. Patience!

Next issue was causing the iOS app to crash when I tried to run it, after following the steps.

*** First throw call stack:
(
	0   CoreFoundation                      0x0000000106a3c1e6 __exceptionPreprocess + 294
	1   libobjc.A.dylib                     0x00000001060d1031 objc_exception_throw + 48
	2   CoreFoundation                      0x0000000106ab1975 +[NSException raise:format:] + 197
	3   Runner                              0x0000000101e3336a +[FIRApp configure] + 352
	4   Runner                              0x0000000101eeef49 -[FLTFirebaseAnalyticsPlugin init] + 185
	5   Runner                              0x0000000101eeee28 +[FLTFirebaseAnalyticsPlugin registerWithRegistrar:] + 168
	6   Runner                              0x0000000101d9723c +[GeneratedPluginRegistrant registerWithRegistry:] + 124
	7   Runner                  <…>

This was because I added the googleservice-info.plist to the runner folder on my own. To get it to work I deleted the file and then opened the Runner.xcodeproj in Xcode, and then used Add File in Xcode to add the googleservice-info.plist file.

Making a To-do List App

Followed this tutorial.

Index is given in the itemBuilder, as itemBuilder is automatically called as many times as it takes to fill its available space (and therefore iterates through the indices of the list). Then passed from there to _buildTodoItem, and built into that item’s _promptRemoveTodoItem call.

Flutter Core Principles for reference.

The tutorial above doesn’t include saving to-do list items. Following this tutorial on saving data locally next. Then, saving data to the cloud.

Saving Locally

Using Shared Preferences just as a way to get my feet wet with saving data. Shared Preferences are deleted when the user uninstalls the app, so they shouldn’t be used for anything that persists between installs or across devices. Also for reading and writing Shared Preferences, use an async function for efficiency, as otherwise it can get too resource-intensive and affect performance.

Setting this up is simple enough but due to the asynchronous nature of it, sometimes the tasks aren’t loaded when the user first opens the app. It might help to put the user on a landing page or something so that the app has time to read the tasks.

Next time: Saving Data to the cloud.

My First Flutter App

Followed Part 1 and Part 2 of the Flutter tutorial.

Hot reload happens automatically when saving the app files (but there’s also a button in the IDE to do it).

If you make big changes, do a full restart instead of a hot restart.

Scaffold: make a layout without needing to align things manually.

Use ThemeData to change the colors and such of the app. It is present inside MaterialApp (like title and home)

There is a Colors constant with a bunch of different preset colors. (eg. Colors.deepPurple)

This tutorial on pusher.com also looks good. It goes into more detail about how everything works, and has several parts.