• Stars
    star
    208
  • Rank 187,913 (Top 4 %)
  • Language
    Python
  • License
    MIT License
  • Created about 13 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

a referrals app for Django

Pinax Referrals

CircleCi Codecov

Table of Contents

About Pinax

Pinax is an open-source platform built on the Django Web Framework. It is an ecosystem of reusable Django apps, themes, and starter project templates. This collection can be found at http://pinaxproject.com.

Important Links

Where you can find what you need:

pinax-referrals

Overview

pinax-referrals provides a site with the ability for users to publish referral links to specific pages or objects and then record any responses to those links for subsequent use by the site.

For example, on an object detail page, the site builder would use a template tag from pinax-referrals to display a referral link that the user of the site can send out in a Tweet. Upon clicking that link, a response to that referral code will be recorded as well as any other activity that the site builder wants to track for that session.

It is also possible for anonymous referral links/codes to be generated which is useful in marketing promotions and the like.

Supported Django and Python Versions

Django / Python 3.6 3.7 3.8
2.2 * * *
3.0 * * *

Documentation

Installation

To install pinax-referrals:

    $ pip install pinax-referrals

Add pinax.referrals to your INSTALLED_APPS setting:

INSTALLED_APPS = [
    # other apps
    "pinax.referrals",
]

See the list of settings to modify pinax-referrals's default behavior and make adjustments for your website.

Add pinax.referrals.middleware.SessionJumpingMiddleware in order to link up a user who registers and authenticate after hitting the initial referral link. Make sure that it comes after the django.contrib.auth.middleware.AuthenticationMiddleware:

MIDDLEWARE = [
    # other middleware
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "pinax.referrals.middleware.SessionJumpingMiddleware",
]

Lastly add pinax.referrals.urls to your urls definition:

urlpatterns = [
    # other urls
    url(r"^referrals/", include("pinax.referrals.urls", namespace="pinax_referrals")),
]

Usage

Referral.create

This is the factory method that the create_referral view calls but it can be called directly in case you needed to integrate with pinax-referrals in a different way.

For example, you might want to automatically give every user a referral code that is emailed to them upon signup. In this case, you could created a one-to-one relationship between their Profile and pinax-referrals' Referral and create a signal receiver for when the Profile is created that calls:

referral = Referral.create(
    user=profile.user,
    redirect_to=reverse("home")
)
profile.referral = referral
profile.save()

Then you could, in the welcome email that you send them upon signup, render their referral url that they could forward on to other users:

    {{ user.get_profile.referral.url }}

The only required parameter for Referral.create is redirect_to. If you don't specify a user it will be recorded as None. This can be useful if you want to attach a relationship between some object in your system to a referral that might not have a user associated with it.

You can also pass in an optional label kwarg to Referral.create if you want to allow your users to create and manage multiple referrals as labeling them becomes important in order to keep track of them.

At runtime, you can append the redirect_to URL parameter to your referral URL to dynamically redirect to an alternate destination.

{{ user.get_profile.referral.url }}?redirect_to=/special/

The URL parameter used can be altered in your settings file.

Referral.record_response

The classmethod record_response will attempt to see if the current user or session has any previous responses to an initial referral and, if so, will then proceed to record the response action.

For example, say you want to record the fact that the user did some site activity after clicking on the referral link you tweeted and subsequently decided to register and login to the site:

from pinax.referrals.models import Referral


def my_view(request, **kwargs):
    # other code
    referral_response = Referral.record_response(request, "SOME_ACTION")

In this case the referral_response will be None if the user on the request doesn't have any previously recorded referral responses. In addition, if the user has responded to more than one Referral code, then this will associate the activity with the most recent response.

In addition, this supports passing an options target keyward argument, if you wanted to record associations with specific objects. For example:

Referral.record_response(request, "SOME_ACTION", target=some_object)

This will record a generic foreign key to some_object that you can use elsewhere to identify activity from your referral at a deeper level than just based on the action label.

Referral.referral_for_request

This class method will give you a referral object for the given request in case you need to apply any business logic in your project. For example, to do any comparisons on the referral.target with another object you have in context for segmenting permissions or authorizations to make your referral system more fine grained.

Settings

PINAX_COOKIE_MAX_AGE

Defaults to None

The total amount of time (in seconds) the cookie lasts in the client's browser.

PINAX_REFERRALS_IP_ADDRESS_META_FIELD

Defaults to "HTTP_X_FORWARDED_FOR"

This is the header value that is retrieved from request.META to record the ip address of the the respondent.

PINAX_REFERRALS_GET_CLIENT_IP_CALLBACK

Defaults to "pinax.referrals.callbacks.get_client_ip"

If the default IP determining function doesn't suit you, supply a path with your own function (takes a request as a parameter).

PINAX_REFERRALS_SECURE_URLS

Defaults to False

Setting this to True will produce urls with https instead of http.

PINAX_REFERRALS_CODE_GENERATOR_CALLBACK

Defaults to "pinax.referrals.callbacks.generate_code"

Externalizes the logic that generates the referral code. pinax-referrals ships with a default that will generate a random 40-character alpha-numeric string that can also be used as a reference implementation. The callable defined by the fully qualified path is passed the class of the referral model (or Referral) and the actual referral model instance. This means that you can easily customize the code for each user.

For example:

def generate_code(referral_class, referral):
    return referral.user.username

Since only one Referral with the same code can exist at the same time the value returned by generate_code needs to be unique.

PINAX_REFERRALS_ACTION_DISPLAY

Defaults to {"RESPONDED": "Clicked on referral link"}

Defines a dictionary mapping action codes for responses to user-friendly display text. Used by the action_display template filter.

PINAX_REFERRALS_REDIRECT_ATTRIBUTE

Defaults to redirect_to

Defines the URL attribute to retrieve dynamic referral redirection URLs from.

The URL is checked by django.utils.http.url_has_allowed_host_and_scheme, so if the domain name is not listed in ALLOWED_HOSTS the view will redirect to Referral.redirec_to path.

Signals

user_linked_to_response is a signal that provides the single argument of a response object that has just been linked to a user. You can use this to provide further automatic processing within your site, such as adding permissions, etc. to users that signup as a result of a referral.

For example:

@receiver(user_linked_to_response)
def handle_user_linked_to_response(sender, response, **kwargs):
    if response.action == "SOME_SPECIAL_ACTION":
        pass  # do something with response.user and response.referral.target (object that referral was linked to)

Templates

pinax-referrals comes with a single template fragment for rendering a simple form that is used in creating a referral link.

_create_referral_form.html

This is a snippet that renders the form that upon submission will create the referral link. By default it is rendered with the class referral with the following context variables:

{
    "url": url,
    "obj": obj,
    "obj_ct": ContentType.objects.get_for_model(obj)
}

or if no object was passed into the create_referral template tag then the context would simply blank for obj and obj_ct.

Template Tags and Filters

create_referral

In order to use pinax-referrals in your project you will use the create_referral template tag wherever you'd like a user to be able to get a referral link to a page or a particular object:

{% load pinax_referrals_tags %}

{% create_referral object.get_absolute_url object %}

The use of object in this case is optional if you just want to record referrals to a particular url. In that case you can just do:

{% load pinax_referrals_tags %}

{% url my_named_url as myurl %}

{% create_referral myurl %}

This will render a form that is defined in pinax/referrals/_create_referral_form.html which will POST to a view and return JSON. The intent of this form is that it be used with an AJAX submission and handler.

The recommended way is to use jquery.form and to do the following:

$(function () {
    $('form.referral').each(function(i, e) {
        var form = $(e);
        options = {
            dataType: "json",
            success: function(data) {
                form.html('<input type="text" value="' + data.url + '" />');
                form.find("input[type=text]").select();
            }
        }
        form.ajaxForm(options);
    });
});

referral_responses

This template tag is an assignment tag that, given a user, sets a context variable with a queryset of all responses for all referrals owned by the user, in order of when they were created.

The use case for this is displaying all the activities associated with the user's different labeled referrals.

Example:

{% load pinax_referrals_tags %}
{% referral_responses user as responses %}

{% for response in responses %}
    {# response is a ReferralResponse object #}
{% endfor %}

action_display

This filter converts a response code into a user friendly display of what that code means. The definitions exist in the setting PINAX_REFERRALS_ACTION_DISPLAY.

{% load pinax_referrals_tags %}

<p>
    {{ response.action|action_display }}
</p>

Development

Migrations

If you need to make migrations for pinax-referrals, run:

    $ python manage.py makemigrations referrals

You may need to do this if you use a custom user model and upgrade Django.

Change Log

4.2.0 (2023-01-12)

  • Added referral model instance parameter to generate_code callback (PINAX_REFERRALS_CODE_GENERATOR_CALLBACK variable)

4.1.0 (2022-12-12)

  • Update to support Django 2.2-4.1, Python 3.7-3.10
  • Fixed admin views performance
  • Fixed AttributeError when referral_responses_for_request() was called with WSGIRequest
  • Added customizable callback for get_client_ip through PINAX_REFERRALS_GET_CLIENT_IP_CALLBACK variable
  • Fixed potential phishing attack risk in redirect_to parameter. Now the parameter is checked with django.utils.http.url_has_allowed_host_and_scheme to prevent redirection to unsafe domain.

4.0.2

  • Added setting to set the cookie's max age in client's browser

4.0.1

  • Changes to admin.py and models.py to increase overridability

4.0.0

  • Drop Django 1.11, 2.0, and 2.1, and Python 2,7, 3.4, and 3.5 support
  • Add Django 2.2 and 3.0, and Python 3.6, 3.7, and 3.8 support
  • Update packaging configs
  • Direct users to community resources

3.0.5

  • Simple fix for #46. Increase the length of the ip_address, so IPv6 address array from HTTP_X_FORWARDED_FOR can be stored.

3.0.4

  • Fixing search in referral admin against "user"

3.0.3

  • Changes to setup.py

3.0.2

  • Use Django 2.0 reverse import

3.0.1

  • Change is_authenticated to property in models.py

3.0.0

  • Add Django 2.0 compatibility testing
  • Drop Django 1.9 and Python 3.3 support
  • Convert CI and coverage to CircleCi and CodeCov
  • Add PyPi-compatible long description
  • Add URL namespacing
  • Standardize documentation layout
  • Drop Django v1.8, v1.10 support
  • Update installation requirements for django>=1.11
  • Remove unused doc build support

2.0.0

  • Renamed from anafero to pinax-referrals
  • Brought up to date with latest Pinax app standards

1.0.1

  • Fix deprecation warning in urls

1.0

  • ENHANCEMENT: made GFK fields on Referral blankable

0.10.0

  • ENHANCEMENT: added a signal to provide notifications of when a referred user authenticates

0.9.1

  • BUG: Fix issue where target response is None

0.9

  • FEATURE: added ability to record a specific object in reference to each response

Migration from 0.8.1

ALTER TABLE "anafero_referralresponse"
 ADD COLUMN "target_content_type_id" integer REFERENCES "django_content_type" ("id") DEFERRABLE INITIALLY DEFERRED,
 ADD COLUMN "target_object_id" integer;

0.8.1

  • ENHANCEMENT: switched over to use django.utils.timezone.now instead of datetime.datetime.now

0.8

  • FEATURE: added ability to override filtering of responses

0.7

  • ENHANCEMENT: Made admin a bit more usable

0.6.1

  • ENHANCEMENT: Rewrote referral_responses to run on Django 1.3

0.6

  • ENHANCEMENT: send full context to the create_referral template tag

0.5.2

  • BUG: Fixed a stupid mistake

0.5.1

  • BUG: fixed an issue with sessions in Django 1.4

0.5

  • FEATURE: added ability to label referrals
  • ENHANCEMENT: added support for bootstrap-ajax.js
  • FEATURE: added a referral_responses assignment template tag
  • FEATURE: added an activity_display template filter
  • ENHANCEMENT: added a new classmethod on Referral for getting a referral object for a given request object.

Migration from 0.4

ALTER TABLE "anafero_referral" ADD COLUMN "label" varchar(100) NOT NULL DEFAULT '';

0.4

  • FEATURE: Add ability to define code generators external to anafero
  • ENHANCEMENT: Add ability to pass in a user to referral.respond in cases when request.user isn't set yet (e.g. during signup)
  • FEATURE: Add ability to get a referral object from a request

0.3

  • FEATURE: changed user on Referral to be nullable, thus enabling anonymous or site administered referral codes

0.2.1

  • BUG: fixed target not being set in the create_referral ajax view

0.2

  • DOC: fixed a typo in the docs
  • ENHANCEMENT: added a response count property
  • ENHANCEMENT: added the return of the referral code along with the URL in the ajax reponse of create_referral
  • BUG: added the return of the proper mimetype in the create_referral ajax view
  • ENHANCEMENT: moved the building of the URL for the referral code to a property on the Referral model
  • FEATURE: added the ability to control referral code generation properties via settings at the site level
  • BUG: fixed the url generation to include https if the site is configured to run SSL
  • BUG: only delete cookies if user is present
  • BUG: make sure to set a session value to prevent session key from changing with each request

0.1

  • initial release

History

This project was originally named anafero and was created by the team at Eldarion. It was later donated to Pinax and at that time renamed to pinax-referrals.

Contribute

Contributing information can be found in the Pinax community health file repo.

Code of Conduct

In order to foster a kind, inclusive, and harassment-free community, the Pinax Project has a Code of Conduct. We ask you to treat everyone as a smart human programmer that shares an interest in Python, Django, and Pinax with you.

Connect with Pinax

For updates and news regarding the Pinax Project, please follow us on Twitter @pinaxproject and check out our Pinax Project blog.

License

Copyright (c) 2012-present James Tauber and contributors under the MIT license.

More Repositories

1

pinax

a Django-based platform for rapidly developing websites
Python
2,624
star
2

django-user-accounts

User accounts for Django
Python
1,109
star
3

django-mailer

mail queuing and management for the Django web framework
Python
721
star
4

pinax-stripe-light

a payments Django app for Stripe
Python
677
star
5

pinax-blog

a blog app for Django
Python
461
star
6

pinax-badges

a badges app for Django
Python
317
star
7

symposion

a Django project for conference websites
Python
300
star
8

pinax-theme-bootstrap

A theme for Pinax based on Twitter's Bootstrap
HTML
269
star
9

pinax-messages

a Django app for allowing users of your site to send messages to each other
Python
197
star
10

django-forms-bootstrap

Bootstrap filter and templates for use with Django forms
Python
175
star
11

pinax-likes

a liking app for Django
Python
156
star
12

pinax-webanalytics

analytics and metrics integration for Django
Python
122
star
13

pinax-project-account

a starter project that incorporates account features from django-user-accounts
119
star
14

pinax-eventlog

An event logger
Python
108
star
15

pinax-invitations

a site invitation app for Django
Python
108
star
16

pinax-comments

a comments app for Django
Python
97
star
17

pinax-models

Provide Support for Logical Deletes on Models and in the Django Admin
Python
90
star
18

pinax-ratings

a ratings app for Django
Python
88
star
19

pinax-starter-projects

Pinax Starter Projects
Shell
79
star
20

django-flag

flagging of inapproriate/spam content
Python
73
star
21

django-waitinglist

DEPRECATED - please see https://github.com/pinax/pinax-waitinglist
Python
64
star
22

pinax-points

a points, positions and levels app for Django
Python
61
star
23

pinax-calendars

Django utilities for publishing events as a calendar
Python
61
star
24

pinax-documents

a document management app for Django
Python
59
star
25

pinax-boxes

database-driven regions on webpages for Django
Python
48
star
26

pinax-teams

an app for Django sites that supports open, by invitation, and by application teams
Python
47
star
27

pinax-starter-app

A starter app template for Pinax apps
Python
36
star
28

pinax-wiki

Easily add a wiki to your Django site
Python
32
star
29

pinax-project-symposion

a starter project demonstrating a minimal symposion instance
HTML
31
star
30

code.pinaxproject.com

the site behind code.pinaxproject.com
Python
29
star
31

pinax-forums

an extensible forums app for Django and Pinax
Python
27
star
32

pinax-project-zero

the foundation for other Pinax starter projects
25
star
33

pinax-waitinglist

a Django waiting list app
Python
25
star
34

pinax-testimonials

a testimonials app for Django
Python
24
star
35

pinax-project-teams

a starter project that has account management, profiles, teams and basic collaborative content.
18
star
36

pinax-images

an app for managing collections of images associated with a content object
Python
17
star
37

pinax-templates

semantic templates for pinax apps
HTML
15
star
38

pinax-phone-confirmation

An app to provide phone confirmation via Twilio
Python
15
star
39

pinax-project-socialauth

a starter project that supports social authentication
CSS
15
star
40

pinax-api

RESTful API adhering to the JSON:API specification
Python
13
star
41

pinax-submissions

an app for proposing and reviewing submissions
Python
12
star
42

pinax-project-blog

a blog starter project
10
star
43

pinax-project-forums

an out-of-the-box Pinax starter project implementing forums
HTML
10
star
44

pinax-images-panel

a React component for uploading and managing images with the pinax-images Django reusable app
JavaScript
9
star
45

pinax-cohorts

Create cohorts to invite to join your private beta site. Depends on pinax-waitinglist.
Python
9
star
46

pinax-pages

A light weight CMS born out of Symposion
Python
8
star
47

pinax-project-lms

A starter project to bring together components of the Pinax Learning Management System
CSS
7
star
48

pinax-cli

a tool for easily instantiating Pinax starter projects (django templates)
Python
7
star
49

django-site-access

an app to provide utilities via middleware to control access to your django site
Python
7
star
50

cloudspotting

a starter project allowing you to create collections of cloud images, view other people’s collections, β€œlike” a collection, etc.
CSS
7
star
51

pinax-calendars-demo

a demo project for pinax-calendars
Python
7
star
52

pinax-lms-activities

framework and base learning activities for Pinax LMS
Python
7
star
53

atom-format

Python
6
star
54

PinaxCon

PinaxCon is a project that demonstrates how Symposion can be hooked up for a conference site
HTML
6
star
55

pinax-events

a simple app for publishing events on your site
Python
5
star
56

pinax-news

a simple app for publishing links to news articles on your site
Python
5
star
57

pinax-utils

an app for Pinax utilities
Python
5
star
58

blog.pinaxproject.com

Python
5
star
59

pinax-types

Python
4
star
60

cloudspotting2

Pinax demo application showing many Pinax apps
CSS
4
star
61

pinax-project-static

3
star
62

pinax-cart

Python
3
star
63

pinax-identity

OpenID Connect with pinax-api helpers
Python
3
star
64

pinax-theme-classic

the original Pinax theme
HTML
3
star
65

pinax_theme_tester

a project based on the zero starter project used to test and build the pinax theme
Python
3
star
66

screencasts

2
star
67

pinax-project-wiki

a demo starter project for a single wiki site, featuring integration of pinax-wiki
2
star
68

lms-activities-demo

a Django site for demoing Pinax LMS Activities
Python
1
star
69

dashboard.pinaxproject.com

a collection of metrics and information about how the Pinax Project is going
Python
1
star
70

.github

Pinax Default Community Health Files
1
star
71

mytweets

a demo of pinax-types periods
Python
1
star
72

pinax-theme-pinaxproject

a Pinax theme for pinaxproject.com website
HTML
1
star
73

patch-game

guess the Pinax patch
CSS
1
star