Attention: Google Chrome request firing twice when url entered manually

I was writing a simple Django view. That view collected data from user request. During the testing I found a problem: data was collecting twice.

I tested my view by copy-pasting url to address bar of Google Chrome. And before I hit “Enter” request apeared in server log.

I have also tested in Firefox and Opera - extra requests did not appear.

The best solution is to avoid changing application state in GET requests. More info at StackExchange

Django admin: how to enable add/edit buttons for many-to-many model relationships

It was pretty easy to add an inline for many-to-many model relationship Django admin, like it was mentioned in the Django documentation.

from django.contrib import admin

class MembershipInline(admin.TabularInline):
    model = Group.members.through

class PersonAdmin(admin.ModelAdmin):
    inlines = [
        MembershipInline,
    ]

class GroupAdmin(admin.ModelAdmin):
    inlines = [
        MembershipInline,
    ]
    exclude = ('members',)

Models:

from django.db import models

class Person(models.Model):
    name = models.CharField(max_length=128)

class Group(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField(Person, related_name='groups')

The trick is that line in admin.py:

model = Group.members.through

But what wasn’t unclear to me is why there is no add/edit buttons on inline items in the Django admin interface, so I couldn’t add or edit any of related model’s objects.

My models.py (simplified):

class OfferGeo(models.Model):
    price = models.PositiveIntegerField()
    goal = models.PositiveIntegerField()

class Offer(models.Model):
    title = models.CharField(max_length=200)
    description = models.TextField()
    geo = models.ManyToManyField(OfferGeo, related_name='offers')

My admin.py (before fix):

from django.contrib import admin
from dashboard.models import *

class GeoInline(admin.TabularInline):
    model = Offer.geo.through

@admin.register(Offer)
class OfferAdmin(admin.ModelAdmin):
    inlines = (GeoInline,)
    exclude = ('geo',) # Excluding field to hide unnecessary field, as mentioned in the docs

My mistake was that I didn’t register related model OfferGeo in admin.py. After adding admin.site.register(OfferGeo) add/edit buttons appeared.

Final admin.py looks like this:

from django.contrib import admin
from dashboard.models import *

admin.site.register(OfferGeo)

class GeoInline(admin.TabularInline):
    model = Offer.geo.through

@admin.register(Offer)
class OfferAdmin(admin.ModelAdmin):
    inlines = (GeoInline,)
    exclude = ('geo',) # Excluding field to hide unnecessary field, as mentioned in the docs

Hope this helps someone else.