@login_required
@unique_session_or_json_redirect
def copyplan(request, planid):
    """
    Copy a plan to a new, editable plan.

    This view is called by the plan chooser and the share plan tab. These
    actions take a template or shared plan, and copy the plan without its
    history into an editable plan in the current user's account.

    Parameters:
        request -- The HttpRequest, which includes the user.
        planid -- The original plan to copy.

    Returns:
        A JSON HttpResponse which includes either an error message or the
        copied plan ID.
    """
    note_session_activity(request)

    if not is_plan_ready(planid):
        return HttpResponseRedirect('/')

    status = { 'success': False }
    p = Plan.objects.get(pk=planid)
    # Check if this plan is copyable by the current user.
    if not can_copy(request.user, p):
        status['message'] = _("User %(username)s doesn't have permission to " \
            "copy this model" % {'username': request.user.username})
        return HttpResponse(json.dumps(status),mimetype='application/json')

    # Create a random name if there is no name provided
    newname = p.name + " " + str(random.random()) 
    if (request.method == "POST" ):
        newname = request.POST["name"][0:200]
        shared = request.POST.get("shared", False)

    plan_copy = Plan.objects.filter(name=newname, owner=request.user, legislative_body=p.legislative_body)
    # Check that the copied plan's name doesn't already exist.
    if len(plan_copy) > 0:
        status['message'] = _("You already have a plan named that. " \
            "Please pick a unique name.")
        return HttpResponse(json.dumps(status),mimetype='application/json')

    plan_copy = Plan(name=newname, owner=request.user, is_shared=shared, legislative_body=p.legislative_body, processing_state=ProcessingState.READY)
    plan_copy.create_unassigned = False
    plan_copy.save()

    # Get all the districts in the original plan at the most recent version
    # of the original plan.
    districts = p.get_districts_at_version(p.version, include_geom=True)
    for district in districts:
        district_copy = copy.copy(district)

        district_copy.id = None
        district_copy.version = 0
        district_copy.is_locked = False
        district_copy.plan = plan_copy

        try:
            district_copy.save() 
        except Exception as inst:
            status["message"] = _("Could not save district copies")
            status["exception"] = inst.message
            return HttpResponse(json.dumps(status),mimetype='application/json')

        # clone the characteristics, comments, and tags from the original 
        # district to the copy 
        district_copy.clone_relations_from(district)

    # Serialize the plan object to the response.
    data = serializers.serialize("json", [ plan_copy ])

    return HttpResponse(data, mimetype='application/json')
dataset/ETHPy150Open PublicMapping/DistrictBuilder/django/publicmapping/redistricting/views.py/copyplan/original