CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-django-countries

A Django application that provides country choices for use with forms, flag icons static files, and a country field for models.

Pending
Overview
Eval results
Files

template-tags.mddocs/

Template Tags

Django template tags for accessing country data in templates. The countries template tag library provides simple interfaces for retrieving individual countries and complete country lists for use in Django templates.

Template Tag Library

Load the countries template tag library in your templates:

{% load countries %}

Capabilities

get_country Tag

Retrieve a Country object for a specific country code.

@register.simple_tag
def get_country(code):
    """
    Get Country object for given country code.
    
    Parameters:
    - code: str - Country code (alpha2, alpha3, or numeric)
    
    Returns:
    - Country: Country object with name, flag, and metadata access
    """

get_countries Tag

Retrieve a list of all available countries.

@register.simple_tag  
def get_countries():
    """
    Get list of all countries as CountryTuple objects.
    
    Returns:
    - List[CountryTuple]: All countries sorted by name
    """

Usage Examples

Basic Country Display

{% load countries %}

<!-- Get specific country -->
{% get_country "US" as usa %}
<div class="country">
    <img src="{{ usa.flag }}" alt="Flag">
    <span>{{ usa.name }}</span>
    <small>({{ usa.code }})</small>
</div>

<!-- Display country properties -->
{% get_country "FR" as france %}
<ul>
    <li>Code: {{ france.code }}</li>
    <li>Name: {{ france.name }}</li>  
    <li>Alpha3: {{ france.alpha3 }}</li>
    <li>Numeric: {{ france.numeric }}</li>
    <li>IOC: {{ france.ioc_code }}</li>
    <li>Flag: <img src="{{ france.flag }}" alt="Flag"></li>
</ul>

Countries List Display

{% load countries %}

<!-- Get all countries -->
{% get_countries as country_list %}
<select name="country">
    <option value="">Select a country</option>
    {% for country in country_list %}
        <option value="{{ country.code }}">{{ country.name }}</option>
    {% endfor %}
</select>

<!-- Country dropdown with flags -->
{% get_countries as all_countries %}
<div class="country-selector">
    {% for country in all_countries %}
        <div class="country-option" data-code="{{ country.code }}">
            {% get_country country.code as country_obj %}
            <img src="{{ country_obj.flag }}" alt="{{ country.name }}" class="flag">
            <span>{{ country.name }}</span>
        </div>
    {% endfor %}
</div>

Conditional Country Display

{% load countries %}

<!-- Check if country exists -->
{% get_country user.country_code as user_country %}
{% if user_country %}
    <p>User is from {{ user_country.name }}</p>
    <img src="{{ user_country.flag }}" alt="Flag" class="user-flag">
{% else %}
    <p>Country not specified</p>
{% endif %}

<!-- Display multiple user countries -->
{% if user.visited_countries %}
    <h3>Visited Countries:</h3>
    <div class="visited-countries">
        {% for country_code in user.visited_countries %}
            {% get_country country_code as country %}
            {% if country %}
                <span class="country-badge">
                    <img src="{{ country.flag }}" alt="{{ country.name }}">
                    {{ country.name }}
                </span>
            {% endif %}
        {% endfor %}
    </div>
{% endif %}

Table Display

{% load countries %}

<table class="countries-table">
    <thead>
        <tr>
            <th>Flag</th>
            <th>Country</th>
            <th>Code</th>
            <th>Alpha3</th>
        </tr>
    </thead>
    <tbody>
        {% get_countries as countries_list %}
        {% for country in countries_list %}
            {% get_country country.code as country_obj %}
            <tr>
                <td><img src="{{ country_obj.flag }}" alt="Flag" width="24"></td>
                <td>{{ country.name }}</td>
                <td>{{ country.code }}</td>
                <td>{{ country_obj.alpha3 }}</td>
            </tr>
        {% endfor %}
    </tbody>
</table>

Form Integration

{% load countries %}

<!-- Custom country select -->
<div class="form-group">
    <label for="country">Country:</label>
    <select id="country" name="country" class="form-control">
        <option value="">Choose country...</option>
        {% get_countries as country_options %}
        {% for country in country_options %}
            <option value="{{ country.code }}" 
                    {% if form.country.value == country.code %}selected{% endif %}>
                {{ country.name }}
            </option>
        {% endfor %}
    </select>
</div>

<!-- Country with flag preview -->
<div class="country-input-group">
    <select id="country-select" name="country" onchange="updateFlag(this.value)">
        <option value="">Select country...</option>
        {% get_countries as available_countries %}
        {% for country in available_countries %}
            <option value="{{ country.code }}">{{ country.name }}</option>
        {% endfor %}
    </select>
    <img id="country-flag" src="/static/flags/__.gif" alt="Flag" class="flag-preview">
</div>

<script>
function updateFlag(countryCode) {
    const flagImg = document.getElementById('country-flag');
    if (countryCode) {
        flagImg.src = `/static/flags/${countryCode.toLowerCase()}.gif`;
        flagImg.alt = `${countryCode} flag`;
    } else {
        flagImg.src = '/static/flags/__.gif';
        flagImg.alt = 'Flag';
    }
}
</script>

Localization Support

{% load countries %}
{% load i18n %}

<!-- Countries in user's language -->
{% get_language as current_lang %}
<div class="language-countries" data-lang="{{ current_lang }}">
    {% get_countries as localized_countries %}
    {% for country in localized_countries %}
        <div class="country-item">
            {% get_country country.code as country_details %}
            <img src="{{ country_details.flag }}" alt="{{ country.name }}">
            <span class="country-name">{{ country.name }}</span>
            <small class="country-code">({{ country.code }})</small>
        </div>
    {% endfor %}
</div>

<!-- Multi-language country display -->
{% get_country "DE" as germany %}
<div class="country-multilang">
    <h4>Germany / Deutschland</h4>
    <p>English: {{ germany.name }}</p>
    {% language 'de' %}
        {% get_country "DE" as deutschland %}
        <p>Deutsch: {{ deutschland.name }}</p>
    {% endlanguage %}
</div>

Country Statistics

{% load countries %}

<!-- Country statistics -->
{% get_countries as all_countries %}
<div class="country-stats">
    <p>Total countries: {{ all_countries|length }}</p>
    
    <!-- Countries by first letter -->
    {% regroup all_countries by name.0 as countries_by_letter %}
    <div class="country-index">
        {% for letter_group in countries_by_letter %}
            <div class="letter-section">
                <h3>{{ letter_group.grouper }}</h3>
                <ul>
                    {% for country in letter_group.list|slice:":5" %}
                        <li>{{ country.name }} ({{ country.code }})</li>
                    {% endfor %}
                    {% if letter_group.list|length > 5 %}
                        <li>... and {{ letter_group.list|length|add:"-5" }} more</li>
                    {% endif %}
                </ul>
            </div>
        {% endfor %}
    </div>
</div>

AJAX Integration

{% load countries %}

<!-- Country search with AJAX -->
<div class="country-search">
    <input type="text" id="country-search" placeholder="Search countries...">
    <div id="country-results"></div>
</div>

<script>
// Country data for client-side search
const countries = [
    {% get_countries as searchable_countries %}
    {% for country in searchable_countries %}
        {% get_country country.code as country_data %}
        {
            code: "{{ country.code }}",
            name: "{{ country.name|escapejs }}",
            flag: "{{ country_data.flag }}"
        }{% if not forloop.last %},{% endif %}
    {% endfor %}
];

document.getElementById('country-search').addEventListener('input', function(e) {
    const query = e.target.value.toLowerCase();
    const results = countries.filter(country => 
        country.name.toLowerCase().includes(query)
    );
    
    const resultsDiv = document.getElementById('country-results');
    resultsDiv.innerHTML = results.map(country => 
        `<div class="country-result" data-code="${country.code}">
            <img src="${country.flag}" alt="Flag">
            <span>${country.name}</span>
        </div>`
    ).join('');
});
</script>

Advanced Usage

Custom Country Templates

<!-- countries/country_card.html -->
{% load countries %}

<div class="country-card" data-country="{{ country_code }}">
    {% get_country country_code as country %}
    {% if country %}
        <div class="country-header">
            <img src="{{ country.flag }}" alt="{{ country.name }}" class="country-flag">
            <h3>{{ country.name }}</h3>
        </div>
        <div class="country-details">
            <span class="country-code">{{ country.code }}</span>
            <span class="country-alpha3">{{ country.alpha3 }}</span>
            {% if country.numeric %}
                <span class="country-numeric">{{ country.numeric }}</span>
            {% endif %}
        </div>
    {% else %}
        <div class="country-not-found">
            <span>Country not found: {{ country_code }}</span>
        </div>
    {% endif %}
</div>

<!-- Usage -->
{% include 'countries/country_card.html' with country_code='US' %}
{% include 'countries/country_card.html' with country_code='FR' %}

Performance Optimization

{% load countries %}

<!-- Cache country list for better performance -->
{% load cache %}
{% cache 3600 countries_dropdown %}
    {% get_countries as cached_countries %}
    <select name="country">
        {% for country in cached_countries %}
            <option value="{{ country.code }}">{{ country.name }}</option>
        {% endfor %}
    </select>
{% endcache %}

<!-- Lazy load country flags -->
<div class="countries-grid">
    {% get_countries as grid_countries %}
    {% for country in grid_countries %}
        {% get_country country.code as country_obj %}
        <div class="country-cell">
            <img data-src="{{ country_obj.flag }}" 
                 alt="{{ country.name }}" 
                 class="lazy-flag"
                 loading="lazy">
            <span>{{ country.name }}</span>
        </div>
    {% endfor %}
</div>

Install with Tessl CLI

npx tessl i tessl/pypi-django-countries

docs

admin-integration.md

countries-registry.md

django-rest-framework.md

form-fields-widgets.md

graphql-support.md

index.md

model-fields.md

template-tags.md

tile.json