{"id":14972749,"url":"https://github.com/app-generator/sample-django-extended-user-profile","last_synced_at":"2025-04-05T17:07:02.998Z","repository":{"id":52791330,"uuid":"348593874","full_name":"app-generator/sample-django-extended-user-profile","owner":"app-generator","description":"Django User Profile - Open-source Django Sample | AppSeed","archived":false,"fork":false,"pushed_at":"2024-10-17T03:31:32.000Z","size":6938,"stargazers_count":92,"open_issues_count":0,"forks_count":35,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-29T06:52:19.674Z","etag":null,"topics":["appseed-sample","django-app","django-application","django-bootstrap","django-bootstrap5","django-bs5","django-coding-sample","django-extended-profile","django-extended-user","django-sample","python-coding-sample"],"latest_commit_sha":null,"homepage":"https://appseed.us/product/volt-dashboard/django/","language":"CSS","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/app-generator.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-03-17T05:47:03.000Z","updated_at":"2025-02-08T16:37:47.000Z","dependencies_parsed_at":"2022-08-22T08:10:24.016Z","dependency_job_id":"92b4f13b-b94d-4b25-9f63-170283daf82f","html_url":"https://github.com/app-generator/sample-django-extended-user-profile","commit_stats":{"total_commits":47,"total_committers":4,"mean_commits":11.75,"dds":"0.44680851063829785","last_synced_commit":"476a99abed5b90dedded99d3fbb9115f98ed383f"},"previous_names":[],"tags_count":4,"template":true,"template_full_name":"app-generator/django-volt-dashboard","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/app-generator%2Fsample-django-extended-user-profile","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/app-generator%2Fsample-django-extended-user-profile/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/app-generator%2Fsample-django-extended-user-profile/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/app-generator%2Fsample-django-extended-user-profile/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/app-generator","download_url":"https://codeload.github.com/app-generator/sample-django-extended-user-profile/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247369952,"owners_count":20927928,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["appseed-sample","django-app","django-application","django-bootstrap","django-bootstrap5","django-bs5","django-coding-sample","django-extended-profile","django-extended-user","django-sample","python-coding-sample"],"created_at":"2024-09-24T13:47:28.465Z","updated_at":"2025-04-05T17:07:02.969Z","avatar_url":"https://github.com/app-generator.png","language":"CSS","funding_links":[],"categories":["CSS"],"sub_categories":[],"readme":"# [Django User Profile](https://django-user-profile.appseed-srv1.com/)\n\nDjango Sample project that allows registered users to edit their profile outside of the admin module. **Django User Profile** is provided on top of `Volt`, a popular open-source **[Django Bootstrap 5](https://appseed.us/product/volt-dashboard/django/)** provided by `Themesberg` and `AppSeed`. For newcomers, **Django** is the most popular Python-based web framework initially released in 2003 and is currently a top-rated framework in web development. \n\n- 👉 [Django User Profile](https://django-user-profile.appseed-srv1.com/) - `LIVE Demo`\n- 👉 [Django Bootstrap 5](https://appseed.us/product/volt-dashboard/django/) - the original starter\n\n\u003cbr /\u003e\n\n---\n\n\u003e For a **complete set of features** and long-term support, check out **[Dynamic Django](https://app-generator.dev/docs/developer-tools/dynamic-django/index.html)**, a powerful starter that incorporates:\n\n- ✅ [Dynamic DataTables](https://app-generator.dev/docs/developer-tools/dynamic-django/datatables.html): using a single line of configuration, the data saved in any table is automatically managed\n- ✅ [Dynamic API](https://app-generator.dev/docs/developer-tools/dynamic-django/api.html): any model can become a secure API Endpoint using DRF\n- ✅ [Dynamic Charts](https://app-generator.dev/docs/developer-tools/dynamic-django/charts.html): extract relevant charts without coding all major types are supported\n- ✅ [CSV Loader](https://app-generator.dev/docs/developer-tools/dynamic-django/csv-loader.html): translate CSV files into Django Models and (optional) load the information\n- ✅ Powerful [CLI Tools](https://app-generator.dev/docs/developer-tools/dynamic-django/cli.html) for the GIT interface, configuration editing, updating the configuration and database (create models, migrate DB)\n\n\u003cbr /\u003e\n\n## How to use it\n\n```bash\n$ # Get the code\n$ git clone https://github.com/app-generator/sample-django-extended-user-profile.git\n$ cd sample-django-extended-user-profile\n$\n$ # Virtualenv modules installation (Unix based systems)\n$ virtualenv env\n$ source env/bin/activate\n$\n$ # Virtualenv modules installation (Windows based systems)\n$ # virtualenv env\n$ # .\\env\\Scripts\\activate\n$\n$ # Install modules - SQLite Storage\n$ pip3 install -r requirements.txt\n$\n$ # Create tables\n$ python manage.py makemigrations\n$ python manage.py migrate\n$\n$ # Start the application (development mode)\n$ python manage.py runserver # default port 8000\n$\n$ # Start the app - custom port\n$ # python manage.py runserver 0.0.0.0:\u003cyour_port\u003e\n$\n$ # Access the web app in browser: http://127.0.0.1:8000/\n```\n\n\u003e Note: To use the app, please access the registration page and create a new user. After authentication, the app will unlock the private pages.\n\n\u003cbr /\u003e\n\n## Codebase structure\n\nThe project is coded using a simple and intuitive structure presented below:\n\n```bash\n\u003c PROJECT ROOT \u003e\n   |\n   |-- core/                               # Implements app logic and serve the static assets\n   |    |-- settings.py                    # Django app bootstrapper\n   |    |-- static/\n   |    |    |-- \u003ccss, JS, images\u003e         # CSS files, Javascripts files\n   |    |-- templates/                     # Templates used to render pages\n   |         |\n   |         |-- includes/                 # HTML chunks and components\n   |         |-- layouts/                  # Master pages\n   |         |-- accounts/                 # Authentication pages\n   |         |\n   |      index.html                       # The default page\n   |       *.html                          # All other HTML pages\n   |\n   |-- authentication/                     # Handles auth routes (login and register)\n   |    |-- urls.py                        # Define authentication routes  \n   |    |-- forms.py                       # Define auth forms  \n   |\n   |-- app/                                # A simple app that serve HTML files\n   |    |-- views.py                       # Serve HTML pages for authenticated users\n   |    |-- urls.py                        # Define some super simple routes  \n   |\n   |-- customers/                          # Handles the profile edit     \u003c-------- NEW\n   |    |-- __init__.py                    # Defines App init             \u003c-------- NEW\n   |    |-- admin.py                       # Defines App admin            \u003c-------- NEW\n   |    |-- apps.py                        # Defines App apps             \u003c-------- NEW\n   |    |-- forms.py                       # Defines App forms            \u003c-------- NEW\n   |    |-- models.py                      # Defines App models           \u003c-------- NEW\n   |    |-- signals.py                     # Defines App signals          \u003c-------- NEW\n   |    |-- tests.py                       # Defines App tests            \u003c-------- NEW\n   |    |-- urls.py                        # Defines App routes           \u003c-------- NEW\n   |    |-- views.py                       # Defines App views            \u003c-------- NEW\n   |\n   |-- requirements.txt                    # Development modules - SQLite storage\n   |-- .env                                # Inject Configuration via Environment\n   |-- manage.py                           # Start the app - Django default start script\n   |\n   |-- ************************************************************************\n```\n\n\u003cbr /\u003e\n\n\u003e The bootstrap flow\n\n- Django bootstrapper `manage.py` uses `core/settings.py` as the main configuration file\n- `core/settings.py` loads the app magic from `.env` file\n- Redirect the guest users to Login page\n- Unlock the pages served by *app* node for authenticated users\n\n\u003cbr /\u003e\n\n## User Profile Feature\n\nThis section describes the coding process for this feature that allows authenticated users to update their profiles. \n\n![Settings screenshot](https://raw.githubusercontent.com/app-generator/django-user-profile/master/media/django-dashboard-volt-screen-settings.png)\n\n\u003cbr /\u003e\n\n### Settings\n\nIn this section, the user can change profile information, including name, email, avatar, ... etc. \nTo do this, we create a new app called `customers`, then create a model named `Profile` to store user information.\n\n### The `customers` app:\n\nThis module will manage the user profile information by defining a new model, form, and view. Authenticated users can also upload their `avatar`. \n\n```bash\n$ python manage.py startapp customers\n```\n\n\u003cbr /\u003e\n\n### The `Profile` model\n\n`customers/models.py`:\n```python\nclass Profile(models.Model):\n\n    # Managed fields\n    user     = models.OneToOneField(User, related_name=\"profile\", on_delete=models.CASCADE)\n    avatar   = models.ImageField(upload_to=\"customers/profiles/avatars/\", null=True, blank=True)\n    birthday = models.DateField(null=True, blank=True)\n    gender   = models.PositiveSmallIntegerField(choices=GENDER_CHOICES, null=True, blank=True)\n    phone    = models.CharField(max_length=32, null=True, blank=True)\n    address  = models.CharField(max_length=255, null=True, blank=True)\n    number   = models.CharField(max_length=32, null=True, blank=True)\n    city     = models.CharField(max_length=50, null=True, blank=True)\n    zip      = models.CharField(max_length=30, null=True, blank=True)\n\n    @property\n    def get_avatar(self):\n        return self.avatar.url if self.avatar else static('assets/img/team/default-profile-picture.png')\n```\n\n\u003e **get_avatar:** In this property, if the avatar value is not provided by the user, the default value is used. \n\n\u003cbr /\u003e\n\n### The `Profile` form\n\nCreate related form to show inputs \u0026 store data. The `ProfileForm` will be defined in the `customers/forms.py` using a definition as below:\n    \n```python\nfrom django import forms\nfrom customers.models import Profile\n\nclass ProfileForm(forms.ModelForm):\n    first_name = forms.CharField(max_length=255)\n    last_name = forms.CharField(max_length=255)\n    email = forms.EmailField()\n\n    class Meta:\n        model = Profile\n        fields = '__all__'\n        exclude = ['user']\n\n\ndef form_validation_error(form):\n    \"\"\"\n    Form Validation Error\n    If any error happened in your form, this function returns the error message.\n    \"\"\"\n    msg = \"\"\n    for field in form:\n        for error in field.errors:\n            msg += \"%s: %s \\\\n\" % (field.label if hasattr(field, 'label') else 'Error', error)\n    return msg\n\n```\n\n\u003e Note: We have three fields (first_name, last_name, email) that are outside the profile model (they are in the user model). We need to add these three fields to our form.\n\n\u003e form_validation_error: If any error happened in your form, this function returns the error message.\n\n\u003cbr /\u003e\n\n### The `Profile` view \n\n* create `ProfileView` in `customers/views.py`:\n\n```python\nfrom django.contrib import messages # import messages to show flash message in your page\nfrom customers.forms import ProfileForm, form_validation_error # import the used form and related function to show errors\nfrom customers.models import Profile # import the Profile Model \n\n\n@method_decorator(login_required(login_url='login'), name='dispatch')\nclass ProfileView(View):\n    profile = None\n\n    def dispatch(self, request, *args, **kwargs):\n        self.profile, __ = Profile.objects.get_or_create(user=request.user)\n        return super(ProfileView, self).dispatch(request, *args, **kwargs)\n\n    def get(self, request):\n        context = {'profile': self.profile}\n        return render(request, 'customers/profile.html', context)\n\n    def post(self, request):\n        form = ProfileForm(request.POST, request.FILES, instance=self.profile)\n\n        if form.is_valid():\n            profile = form.save()\n            \n            # to save user model info\n            profile.user.first_name = form.cleaned_data.get('first_name')\n            profile.user.last_name  = form.cleaned_data.get('last_name')\n            profile.user.email      = form.cleaned_data.get('email')\n            profile.user.save()\n            \n            messages.success(request, 'Profile saved successfully')\n        else:\n            messages.error(request, form_validation_error(form))\n        return redirect('profile')\n```\n\n\u003e dispatch method: In this section, if the user does not have a profile, it will be created and the value of the profile object will set in the profile field.\n\n\u003cbr /\u003e\n\n### The `Profile` HTML template\n\nThe template that handles the user input is defined in `customers/profile.html` file. \n\n```html\n\n    \u003cform action=\"{% url 'profile' %}\" method=\"POST\" enctype=\"multipart/form-data\"\u003e\n\n        {% csrf_token %}\n\n        \u003cdiv\u003e\n            \u003clabel for=\"first_name\"\u003eFirst Name\u003c/label\u003e\n            \u003cinput name=\"first_name\" class=\"form-control\" id=\"first_name\" type=\"text\"\n                    placeholder=\"Enter your first name\" value=\"{{ profile.user.first_name }}\"\n                    required\u003e\n        \u003c/div\u003e\n\n        \u003cdiv\u003e\n            \u003clabel for=\"last_name\"\u003eLast Name\u003c/label\u003e\n            \u003cinput name=\"last_name\" class=\"form-control\" id=\"last_name\" type=\"text\"\n                    placeholder=\"Also your last name\" value=\"{{ profile.user.last_name }}\"\n                    required\u003e\n        \u003c/div\u003e\n\n        \u003clabel for=\"gender\"\u003eGender\u003c/label\u003e\n        \u003cselect name=\"gender\" class=\"form-select mb-0\" id=\"gender\"\n                aria-label=\"Gender select example\"\u003e\n            \u003coption selected\u003eGender\u003c/option\u003e\n            {% for key, value in profile.GENDER_CHOICES %}\n                \u003coption value=\"{{ key }}\"\n                        {% if profile.gender == key %}selected{% endif %}\u003e{{ value }}\u003c/option\u003e\n            {% endfor %}\n        \u003c/select\u003e\n\n        \u003c!-- And the rest of the fields --\u003e\n\n    \u003c/form\u003e\n```\n\n\u003e Note: Make sure there is **`enctype=\"multipart/form-data\"`** attribute in the form tag to upload the avatar.\n\n\u003cbr /\u003e\n\n### The `Profile` routing\n\nActivate the routing for `customers` app by edit the `customers/urls.py` file with the following code:\n\n```python\nfrom django.urls import path\nfrom customers import views\n\nurlpatterns = [\n    path('profile/', views.ProfileView.as_view(), name='profile'),\n]\n```\n\n**Update `core/urls`** to include `customers` urls:\n\n```python\nfrom django.conf import settings\nfrom django.contrib import admin\nfrom django.conf.urls.static import static\nfrom django.urls import path, include\n\nurlpatterns = [\n    path('admin/', admin.site.urls),  # Django admin route\n    path('customers/', include(\"customers.urls\")),  # Django customers route\n    # ...\n]\n\n# to support and show media \u0026 static files in developer mode\nif settings.DEVEL:\n    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)\n    urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)\n```\n\n\u003cbr /\u003e\n\n### Links \u0026 Resources\n\n- [Django](https://www.djangoproject.com/) - the official website\n- More [Django Templates](https://themesberg.com/templates/django) provided by Themesberg \n- More [Django Dashboards](http://appseed.us/admin-dashboards/django) provided by AppSeed\n\n\u003cbr /\u003e\n\n---\n[Django Template Volt](https://appseed.us/product/volt-dashboard/django/) - Provided by Themesberg and AppSeed.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapp-generator%2Fsample-django-extended-user-profile","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fapp-generator%2Fsample-django-extended-user-profile","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapp-generator%2Fsample-django-extended-user-profile/lists"}