Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/app-generator/sample-django-extended-user-profile

Django User Profile - Open-source Django Sample | AppSeed
https://github.com/app-generator/sample-django-extended-user-profile

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

Last synced: 3 days ago
JSON representation

Django User Profile - Open-source Django Sample | AppSeed

Awesome Lists containing this project

README

        

# [Django User Profile](https://django-user-profile.appseed-srv1.com/)

Django 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.

- 👉 [Django User Profile](https://django-user-profile.appseed-srv1.com/) - `LIVE Demo`
- 👉 [Django Bootstrap 5](https://appseed.us/product/volt-dashboard/django/) - the original starter


---

> 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:

- ✅ [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
- ✅ [Dynamic API](https://app-generator.dev/docs/developer-tools/dynamic-django/api.html): any model can become a secure API Endpoint using DRF
- ✅ [Dynamic Charts](https://app-generator.dev/docs/developer-tools/dynamic-django/charts.html): extract relevant charts without coding all major types are supported
- ✅ [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
- ✅ 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)


## How to use it

```bash
$ # Get the code
$ git clone https://github.com/app-generator/sample-django-extended-user-profile.git
$ cd sample-django-extended-user-profile
$
$ # Virtualenv modules installation (Unix based systems)
$ virtualenv env
$ source env/bin/activate
$
$ # Virtualenv modules installation (Windows based systems)
$ # virtualenv env
$ # .\env\Scripts\activate
$
$ # Install modules - SQLite Storage
$ pip3 install -r requirements.txt
$
$ # Create tables
$ python manage.py makemigrations
$ python manage.py migrate
$
$ # Start the application (development mode)
$ python manage.py runserver # default port 8000
$
$ # Start the app - custom port
$ # python manage.py runserver 0.0.0.0:
$
$ # Access the web app in browser: http://127.0.0.1:8000/
```

> Note: To use the app, please access the registration page and create a new user. After authentication, the app will unlock the private pages.


## Codebase structure

The project is coded using a simple and intuitive structure presented below:

```bash
< PROJECT ROOT >
|
|-- core/ # Implements app logic and serve the static assets
| |-- settings.py # Django app bootstrapper
| |-- static/
| | |-- # CSS files, Javascripts files
| |-- templates/ # Templates used to render pages
| |
| |-- includes/ # HTML chunks and components
| |-- layouts/ # Master pages
| |-- accounts/ # Authentication pages
| |
| index.html # The default page
| *.html # All other HTML pages
|
|-- authentication/ # Handles auth routes (login and register)
| |-- urls.py # Define authentication routes
| |-- forms.py # Define auth forms
|
|-- app/ # A simple app that serve HTML files
| |-- views.py # Serve HTML pages for authenticated users
| |-- urls.py # Define some super simple routes
|
|-- customers/ # Handles the profile edit <-------- NEW
| |-- __init__.py # Defines App init <-------- NEW
| |-- admin.py # Defines App admin <-------- NEW
| |-- apps.py # Defines App apps <-------- NEW
| |-- forms.py # Defines App forms <-------- NEW
| |-- models.py # Defines App models <-------- NEW
| |-- signals.py # Defines App signals <-------- NEW
| |-- tests.py # Defines App tests <-------- NEW
| |-- urls.py # Defines App routes <-------- NEW
| |-- views.py # Defines App views <-------- NEW
|
|-- requirements.txt # Development modules - SQLite storage
|-- .env # Inject Configuration via Environment
|-- manage.py # Start the app - Django default start script
|
|-- ************************************************************************
```


> The bootstrap flow

- Django bootstrapper `manage.py` uses `core/settings.py` as the main configuration file
- `core/settings.py` loads the app magic from `.env` file
- Redirect the guest users to Login page
- Unlock the pages served by *app* node for authenticated users


## User Profile Feature

This section describes the coding process for this feature that allows authenticated users to update their profiles.

![Settings screenshot](https://raw.githubusercontent.com/app-generator/django-user-profile/master/media/django-dashboard-volt-screen-settings.png)


### Settings

In this section, the user can change profile information, including name, email, avatar, ... etc.
To do this, we create a new app called `customers`, then create a model named `Profile` to store user information.

### The `customers` app:

This module will manage the user profile information by defining a new model, form, and view. Authenticated users can also upload their `avatar`.

```bash
$ python manage.py startapp customers
```


### The `Profile` model

`customers/models.py`:
```python
class Profile(models.Model):

# Managed fields
user = models.OneToOneField(User, related_name="profile", on_delete=models.CASCADE)
avatar = models.ImageField(upload_to="customers/profiles/avatars/", null=True, blank=True)
birthday = models.DateField(null=True, blank=True)
gender = models.PositiveSmallIntegerField(choices=GENDER_CHOICES, null=True, blank=True)
phone = models.CharField(max_length=32, null=True, blank=True)
address = models.CharField(max_length=255, null=True, blank=True)
number = models.CharField(max_length=32, null=True, blank=True)
city = models.CharField(max_length=50, null=True, blank=True)
zip = models.CharField(max_length=30, null=True, blank=True)

@property
def get_avatar(self):
return self.avatar.url if self.avatar else static('assets/img/team/default-profile-picture.png')
```

> **get_avatar:** In this property, if the avatar value is not provided by the user, the default value is used.


### The `Profile` form

Create related form to show inputs & store data. The `ProfileForm` will be defined in the `customers/forms.py` using a definition as below:

```python
from django import forms
from customers.models import Profile

class ProfileForm(forms.ModelForm):
first_name = forms.CharField(max_length=255)
last_name = forms.CharField(max_length=255)
email = forms.EmailField()

class Meta:
model = Profile
fields = '__all__'
exclude = ['user']

def form_validation_error(form):
"""
Form Validation Error
If any error happened in your form, this function returns the error message.
"""
msg = ""
for field in form:
for error in field.errors:
msg += "%s: %s \\n" % (field.label if hasattr(field, 'label') else 'Error', error)
return msg

```

> 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.

> form_validation_error: If any error happened in your form, this function returns the error message.


### The `Profile` view

* create `ProfileView` in `customers/views.py`:

```python
from django.contrib import messages # import messages to show flash message in your page
from customers.forms import ProfileForm, form_validation_error # import the used form and related function to show errors
from customers.models import Profile # import the Profile Model

@method_decorator(login_required(login_url='login'), name='dispatch')
class ProfileView(View):
profile = None

def dispatch(self, request, *args, **kwargs):
self.profile, __ = Profile.objects.get_or_create(user=request.user)
return super(ProfileView, self).dispatch(request, *args, **kwargs)

def get(self, request):
context = {'profile': self.profile}
return render(request, 'customers/profile.html', context)

def post(self, request):
form = ProfileForm(request.POST, request.FILES, instance=self.profile)

if form.is_valid():
profile = form.save()

# to save user model info
profile.user.first_name = form.cleaned_data.get('first_name')
profile.user.last_name = form.cleaned_data.get('last_name')
profile.user.email = form.cleaned_data.get('email')
profile.user.save()

messages.success(request, 'Profile saved successfully')
else:
messages.error(request, form_validation_error(form))
return redirect('profile')
```

> 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.


### The `Profile` HTML template

The template that handles the user input is defined in `customers/profile.html` file.

```html

{% csrf_token %}


First Name


Last Name

Gender

Gender
{% for key, value in profile.GENDER_CHOICES %}
{{ value }}
{% endfor %}


```

> Note: Make sure there is **`enctype="multipart/form-data"`** attribute in the form tag to upload the avatar.


### The `Profile` routing

Activate the routing for `customers` app by edit the `customers/urls.py` file with the following code:

```python
from django.urls import path
from customers import views

urlpatterns = [
path('profile/', views.ProfileView.as_view(), name='profile'),
]
```

**Update `core/urls`** to include `customers` urls:

```python
from django.conf import settings
from django.contrib import admin
from django.conf.urls.static import static
from django.urls import path, include

urlpatterns = [
path('admin/', admin.site.urls), # Django admin route
path('customers/', include("customers.urls")), # Django customers route
# ...
]

# to support and show media & static files in developer mode
if settings.DEVEL:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
```


### Links & Resources

- [Django](https://www.djangoproject.com/) - the official website
- More [Django Templates](https://themesberg.com/templates/django) provided by Themesberg
- More [Django Dashboards](http://appseed.us/admin-dashboards/django) provided by AppSeed


---
[Django Template Volt](https://appseed.us/product/volt-dashboard/django/) - Provided by Themesberg and AppSeed.