Django Model-Owner

The option to make a model owned by a user is actually documented for the Django Admin app. However, for reference, here are the steps:

First, the model you want to have an owner needs to reference “User” as a foreign key: (in models.py)

class Website(models.Model):
    submitted_by = models.ForeignKey(User, on_delete=models.CASCADE)
    url = models.URLField()

Provided you want to use this model in Django-Admin, there is an explicit method the app provides when defining admin models: (in admin.py)

@admin.register(Website)
class WebsiteAdmin(ModelAdmin):
    model = Website
    list_display = ('url', )
    exclude = ('submitted_by', )

    def save_model(self, request, obj, form, change):
      if not change:
        # only add owner if not changed object
        obj.owner = request.user
      super().save_model(request, obj, form, change)

A heads-up: Django documentation is explicit that both save_model and delete_model have to call the corresponding super()-method in order to actually save the modified model. Reasoning here is these methods are meant to interact with the process and add extra steps, they are not meant to veto.

Additional thoughts: For a model having an owner is really convenient in plenty of situations, in particular when managing permission. The field can e.g. be matched when viewing details of an object.

There are other, potentially more flexible approaches to the problem. In particular when solving in custom views, the field has to be set manually. The same is true when using more complete solutions like “django-guardian”.

usermanagement with django allauth.

usermanagement with django allauth: It is common for bots to register with a website. Often enough there are users instances in the user base that have registered at some point but did not verify their email-address.

Fortunately enough, for users of django and the excellent django-allauth, there are easy ways to manage these users.

First, the django ORM comes with an easy way to identify these users that did not verify their primary email:

>>> from django.contrib.auth.models import User
>>> unverified_users = User.objects.filter(emailaddress__verified=False, emailaddress__primary=True)
Bot User Management with django allauth
Mobile Phone User – Munich

The ORM allows simple filtering for unverified email addresses through a “relationship lookup”, that is emailaddress__verified=False in the above snippet. Of course, you may want to limit users for which the primary email address is unverified. That is the 2nd keyword argument to .filter() here: emailaddress__primary=True. The filter operator ANDs together these two conditions.

To identify users that not only have unverified, primary email addresses, but also appear to be idle, you may limit users that didn’t login through .exclude():

>> import datetime
>> old_unverified_users = unverified_users.exclude(last_login__gt=datetime.date(2020, 1, 1))

Will only give you users that have logged in after Jan 1st, 2020. Of course, the argument to last_login can be modified to match your requirements.

Finally, you may chose to either email these users and re-ask to verify their email. That would be a separate task, though. In our case, we simply delete these, since they are obviously not interessted in using our site:

old_unverified_users.delete() 

Django 3.0 alpha1 released

A major version bump, with the largest change being built in support for ASGI, the Asynchronous Server Gateway Interface, that previously could be included via channels.

The biggest benefits ASGI offers over the traditional WSGI, is the possibility to build asynchronous operations in webapps, and leverage e.g. WebSockets to push information to the client.

Here are the in-development release notes: Django 3.0 release notes – UNDER DEVELOPMENT | Django documentation