Welcome to the documentation for the "Social network" project!
This project is a Django-based web application that allows users to save and manage image bookmarks and share them with other users. "Social network" provides a convenient and intuitive interface for loading, viewing and managing images.
"Social network" provides a convenient image storage platform that can be used as a personal directory or public gallery. Each user can create their own account, upload their images and add descriptions to them. In addition, users can mark the images they like and view the popular and best ones.
The main features of the "Social network" project include:
- Loading and saving images with description.
- View, manage and search for downloaded images.
- Ability to mark your favorite images.
- Display popular and best images.
- Integration with social networks for user authorization.
This documentation contains a description of each component of the project, its functionality, usage and configuration. You will also find code examples to better understand how to use the various features of the project.
The architecture of the "Social network" project is based on the Django framework, which provides convenient tools for developing web applications. The project has a modular structure, where each application is responsible for a specific functionality. There are three applications in the project: "account", "images" and "actions".
- Application "account":
- This application is responsible for managing user accounts.
- It implements a user authentication and authorization system.
- Users can create an account, log in, change their details and reset their password.
- The "account" application contains models for representing users and their profiles, as well as forms for entering user data.
- Application "images":
- This application is responsible for downloading, viewing and managing images.
- Users can upload their images, add descriptions to them and view them in various formats.
- The "images" application contains models for presenting images, forms for uploading images, views for handling requests, and templates for displaying images on web pages.
- Application "actions":
- This app is responsible for tracking user activities.
- Functions are implemented here to create records of user actions, such as adding a bookmark, tagging an image, etc.
- The "actions" application contains a model for recording user actions and a signal function for automatically updating the action counter when data changes.
- The project uses a URL routing system that determines which views and functions handle different requests.
- Templates are used to display data on web pages, making it easy for users to create an interface.
- Django models are used to represent the data in the database, allowing efficient interaction with the data.
- The "actions" app uses Django signals to automatically update data when the state changes.
- Input requests from users are handled by views and functions in their respective applications.
- Applications interact with data models to retrieve, create, and modify data.
- If necessary, user actions are recorded in the database using the "actions" application.
- Templates define the look and feel of web pages, while static files (CSS, JavaScript, and images) provide the styling and functionality of the interface.
The main functions of the "Social network" project include:
-
Image Upload:
- The user can register or log into their account.
- After a successful login, the user is redirected to the image upload page.
- The user can choose how to download: from a computer or from a URL.
- In the case of uploading from a computer, the user selects an image from the local device and submits the form.
- In the case of URL upload, the user enters the URL of the image and submits the form.
- The server checks the uploaded image for validity and stores it on the server, and creates a record of the uploaded image in the database.
- After a successful upload, the user will be redirected to a page with detailed information about the uploaded image.
-
Image Viewer:
- Registered users can view a list of all uploaded images on the site.
- Users can view other users' uploaded images by going to image detail pages.
-
Add description:
- After uploading an image, the user goes to a page with detailed information about it.
- On this page, the user can add a description to the image in the text field.
- After adding a description, the user can save it and update the record in the database.
-
Likes and comments:
- After viewing the image, the user can "like" the image they like.
- The system keeps track of who "liked" a certain image and when.
- The user can also leave a comment below the image to share their opinion or feedback.
-
Search and filter:
- The application provides the ability to search images by keywords or tags.
- Users can filter images by upload date, popularity or other parameters.
-
Image Rating:
- The application keeps track of the number of "likes" for each image.
- Users can view a list of the most popular or liked images by using the rating or the number of "likes".
-
Update and delete:
- Registered users have access to update and delete their uploaded images and their descriptions.
-
Social interaction:
- The application may provide the ability for users to share their bookmarks with friends or followers on social networks.
-
View rating:
- Users can view the list of the most popular images or users on a special rating page.
The views.py
file in the "account" application does the following:
-
user_login(request)
: This view handles user login. If the request is by POST method and the form is valid, then the login and password entered by the user are checked. If the data is correct and the account is active, then the user is authorized in the system and the message "Authenticated successfully" is displayed. If the account is inactive, the message "Disabled account" is displayed. In case of an invalid login, the message "Invalid login" is displayed. If the request is by GET method, then the login form is displayed on the "account/login.html" page. -
dashboard(request)
: This view shows the "dashboard" to the user when they are already logged in. This retrieves actions (actions) that do not belong to the current user, as well as actions of users that the current user is following (users that he "followed" - "following"). The filtered actions are then displayed on the "account/dashboard.html" page. -
register(request)
: This view handles the registration of new users. If the POST request is valid and the form is valid, a new user account is created and a profile (Profile
) is created for that user. An action is also created using thecreate_action
function, which indicates that the user has created an account. After successful registration, the user is redirected to the "account/register_done.html" page with information about successful registration. -
edit(request)
: This view allows the user to edit their profile. If the POST request and the data and profile forms are valid, then the data is updated and the user is shown a message that the profile has been successfully updated. Otherwise, an error message is displayed. If the request is by GET method, then user and profile data editing forms are displayed on the "account/edit.html" page. -
user_list(request)
: This view lists the users who are active on the system (that is, who have theis_active=True
flag set). The list of users is displayed on the "account/user/list.html" page. -
user_detail(request, username)
: This view displays details about a particular user based on their username (username
). If such a user exists and the account is active, then the user's details are displayed on the "account/user/detail.html" page. Otherwise, a 404 error occurs. -
user_follow(request)
: This view handles the "follow" or "unfollow" action of another user. The request must be a POST method. If the "id" and "action" parameters are present in the POST request, then an attempt is made to get the user with the specified "id". If the action is "follow", then a "Contact" relationship is created between the current user (request.user
) and the specified user (user
). With the "unfollow" action, the "Contact" link is removed. In both cases, an action is also created using thecreate_action
function.
The urls.py
file in the "account" application defines routes (URL patterns) and associates them with views. Each route specifies which view should be called when a particular URL is requested. Here's what each route does:
-
path('', include('django.contrib.auth.urls'))
: This route usesinclude
to include URL patterns provided by Django'sdjango.contrib.auth
application. It includes standard login, login, logout, and change password views that Django provides out of the box. Since this string is at the very beginning, it will match against an empty URL (e.g. "http://example.com/") and all URL patterns fromdjango.contrib.auth.urls
will be added to this application's URL configuration. -
path('', views.dashboard, name='dashboard')
: This route matches an empty URL such as "http://example.com/". It calls theviews.dashboard
view function when the user requests the root URL (the home page). The name of the route is set to "dashboard" so that it can be referenced in templates and other parts of the application. -
path('register/', views.register, name='register')
: This route maps to the URL "http://example.com/register/". It calls the view functionviews.register
when the user navigates to this URL. The route name is set to "register". -
path('edit/', views.edit, name='edit')
: This route maps to the URL "http://example.com/edit/". It calls theviews.edit
view function when the user navigates to this URL. The route name is set to "edit". -
path('users/', views.user_list, name='user_list')
: This route maps to the URL "http://example.com/users/". It calls theviews.user_list
view function when the user navigates to this URL. The route name is set to "user_list". -
path('users/follow/', views.user_follow, name='user_follow')
: This route matches the URL "http://example.com/users/follow/". It calls theviews.user_follow
view function when the user sends a POST request to this URL. The route name is set to "user_follow". -
path('users/<username>/', views.user_detail, name='user_detail')
: This route uses<username>
as a route variable. It matches a URL like "http://example.com/users/username/" where "username" can be replaced with a specific username. This route calls theviews.user_detail
view function, which handles the request to view the details of a specific user. The route name is set to "user_detail".
The models.py
file in the "account" application contains the definition of data models, which are used to store information about user profiles and relationships between users (subscriptions to each other). Here's what these models do:
-
Profile
: This is a model for storing additional information about the user's profile. It is linked to the User model through the "OneToOneField" relationship. Each profile (Profile
) is associated with one and only one user (User), and each user can have only one profile. The following fields are defined in this model:user
: OneToOneField associates a profile with a user. When a user is deleted, the associated profile will also be deleted (on_delete=models.CASCADE
).date_of_birth
: A field to store the user's date of birth.photo
: Field to upload user profile picture.
-
Contact
: This is a model for storing links between users (subscriptions to each other). The following fields are defined in this model:user_from
: ForeignKey associates the relationship with the sender of the subscription. One user can be the sender of severalContact
.user_to
: ForeignKey associates the relationship with the recipient of the subscription. One user can be the recipient of severalContact
.created
: A DateTimeField that stores the date and time the connection (subscription) was created.
This model is used to track "subscription" relationships between users. When a user follows another user, a new entry is created in the
Contact
model that indicates the relationship between the sender and the recipient. -
user_model.add_to_class('following', models.ManyToManyField('self', through=Contact, related_name='followers', symmetrical=False))
: This line of code adds a "following" field to the User model. The "following" field is a ManyToManyField that associates the user with himself. It is used to store subscription relationships between users.The
through=Contact, related_name='followers', symmetrical=False
parameters indicate that the "subscription" relationship is defined through theContact
model, and also specify the reverse name for the feedback. For example, if we have user A and user B is following user A, then we can access the relationship from the user model via thefollowers
attribute, which will return all users that follow user A.
The overall result is the definition of the Profile
and Contact
models, which allow you to store additional information about users and keep track of relationships between users (subscriptions). These models are used to organize the data in the account application and maintain relationships between users.
The forms.py
file in the "account" application contains the form definitions for handling user input. Forms allow you to receive and validate the data entered by users and perform the necessary processing before saving it to the database. Here's what these forms do:
-
LoginForm
: This is the user login form. It contains two fields:username
: CharField to enter the username.password
: CharField for entering a password using the PasswordInput widget to hide entered password characters.
-
UserRegistrationForm
: This is the registration form for new users. It inherits fromforms.ModelForm
, which allows you to use theUser
model to automatically generate form fields. It contains the following fields:username
: CharField to enter the username.first_name
: CharField to enter the username.email
: CharField to enter the user's email.password
: CharField for entering a password using the PasswordInput widget to hide entered password characters.password2
: CharField for password re-entry using the PasswordInput widget. In addition, theclean_password2()
method is defined, which checks that the values of thepassword
andpassword2
fields match. Aclean_email()
method is also defined, which checks that the email entered is not in use by another user.
-
UserEditForm
: This is the user editing form. It also inherits fromforms.ModelForm
and uses theUser
model. The form contains the following fields:first_name
: CharField to enter the username.last_name
: CharField to enter the user's last name.email
: CharField to enter the user's email. Aclean_email()
method is defined that checks that the entered email is not in use by another user other than the current user.
-
ProfileEditForm
: This is the user profile editing form. It inherits fromforms.ModelForm
and uses theProfile
model. The form contains the following fields:date_of_birth
: DateField to enter the user's date of birth.photo
: ImageField to load the user's profile picture.
When a user submits a form to the server, the data from the form is processed and validated by the clean_*
methods, and then saved to the appropriate models (User
or Profile
). Forms allow you to conveniently and securely collect information from users and provide data integrity checks before saving to the database.
The authentication.py
file in the "account" application contains a custom authentication backend and a function for creating user profiles. Here's what they do:
-
EmailAuthBackend
: This class represents a custom authentication backend based on the user's email. When a user tries to log in, authentication is not by username, but by email. It has two methods:-
authenticate(self, request, username=None, password=None)
: This method attempts to find a user by the specified email (username
) in theUser
model. If a user with such an email is found, then the entered password is checked using thecheck_password()
method. If the password is correct, the user is successfully authenticated and the function returns the user object (user
). Otherwise, the function returnsNone
and the user cannot be authenticated. -
get_user(self, user_id)
: This method is used by Django to get a user by theiruser_id
. If a user with the specifieduser_id
is found, then the function returns the user object (user
), otherwise it returnsNone
.
-
-
create_profile(backend, user, *args, **kwargs)
: This is the function that is called when the user is successfully authenticated. It creates a profile (Profile
) for the user, if one does not already exist. This is especially useful if profiles are created automatically for each new user. Theget_or_create()
function is used to ensure that the profile is only created once per user.
These components allow the user to authenticate with an email instead of a username and allow for automatic creation of user profiles upon successful authentication. To use this custom authentication backend, it must be configured in the Django settings as the authentication backend to use.
The apps.py
file in the "account" application contains the configuration of this application for Django. Here is what it does:
-
from django.apps import AppConfig
: This line imports theAppConfig
class from thedjango.apps
module, which provides functionality for configuring and naming the application. -
class AccountConfig(AppConfig)
: This is the "account" application configuration class that inherits fromAppConfig
. It is used to define settings and metadata for a given application. -
default_auto_field = 'django.db.models.BigAutoField'
: This line sets the default value for the primary key auto field (AutoField
). In Django 3.2 and newer,BigAutoField
is the default for primary key fields that are automatically incremented. If your application was created before Django 3.2, adding this line allows you to explicitly indicate that you want to useBigAutoField
. -
name = 'account'
: This line sets the application name to "account". This name is used by Django to identify the application in various places such as project settings, URL patterns, and other components.
The apps.py
file does not perform active functionality in the application, but provides configuration and metadata that can be used by Django to properly identify and set up the "account" application within a project.
This code represents the admin.py
file from the "account" application. This file contains the administrative interface settings for the Profile
model. Here is what this code does:
-
from django.contrib import admin
: This line imports theadmin
module from Django, which provides the admin interface functionality. -
from .models import Profile
: This line imports theProfile
model from the current "account" application. -
@admin.register(Profile)
: This decorator registers theProfile
model in the Django admin interface. This means that theProfile
model will be displayed and edited in the admin panel. -
class ProfileAdmin(admin.ModelAdmin)
: This is the class that defines the administrative interface settings for theProfile
model. It inherits fromadmin.ModelAdmin
, which allows you to customize the display and behavior of the model in the admin panel. -
list_display
: This attribute specifies which fields of theProfile
model will be displayed in the list of records in the admin panel. In this case, the fields 'user', 'date_of_birth' and 'photo' are displayed. -
raw_id_fields
: This attribute determines which fields of theProfile
model will be displayed as value selection links. In this case, the 'user' field will be displayed as a link to select the user associated with the profile to make it easier to select a user, especially if there are many.
These settings allow administrators to manage the Profile
model in the Django admin panel, displaying the required fields and providing a convenient way to select related users.
The base.html
file in the application "account/templates" is the base template that is used to create other HTML pages in the project. This template defines the general structure of the page and contains some dynamic elements. Here is what it does:
-
{% load static %}
: This tag loads static files (such as CSS and JavaScript) for use in the template. -
<title>{% block title %}{% endblock %}</title>
: This tag defines the title of the page. It uses a Django block (block
) named "title", which means it can be overridden in templates that extend this base template. When other templates extend this one, they can define their own title for the page. -
<link href="{% static "css/base.css" %}" rel="stylesheet">
: This tag includes the "base.css" stylesheet file, which is located in the "static/css/" folder of your "account" application. -
<div id="header">
: This block defines the top of the page (header) and contains the "Bookmarks" logo and navigation menu for authenticated users. Depending on the user's authentication status, the menu will contain links to "My dashboard", "Images" and "People" or a "Log-in" link. -
<span class="user">
: This block displays information about the user, such as their greeting and a logout link if the user is authenticated, or a login link if the user is not authenticated. -
{% if messages %}
: This block displays messages for the user, if any. Messages can be of various types (eg success, warning, error) and can be used to display information about successful operations or errors that have occurred on the server. -
<div id="content">
: This block defines a page content area that can be filled with specific content in templates that extend this base template. Content is defined using blocks (block content
). -
<script>
: This block includes helper JavaScript code for handling events on the page. It also includes thejs-cookie
library for handling cookies.
In general, this file provides a general page layout that can be extended and populated with content in templates that use this base template.
The base.css
file in the "account/static" folder defines the styles for the HTML templates in the "account" application. Here is what it does:
-
@import url(//fonts.googleapis.com/css?family=Muli);
: This import includes the "Muli" font from Google Fonts. -
Definition of base styles:
- Defines the general style for the
body
, removes the indentation (margin
) and indentation (padding
) for all content, and also specifies the font for the text. - Specifies the style for paragraphs (
p
) with a set line spacing (line-height
). - Defines style for links (
a
) with color and underlining disabled (text-decoration
). - The style for links (
a:hover
) is defined when hovering the mouse pointer, the color of the link changes.
- Defines the general style for the
-
Defining heading styles (
h1
,h2
,h3
,h4
,h5
,h6
):- Use "Muli" font for headings with normal weight (
font-weight:normal
).
- Use "Muli" font for headings with normal weight (
-
Styles for various page elements such as header (
#header
) and content area (#content
). -
Defining styles for forms:
- Styling input fields, buttons, error messages and help text (
helptext
).
- Styling input fields, buttons, error messages and help text (
-
Defining styles for messages (
messages
), such as success (success
), warning (warning
), error (error
) and information (info
). -
Styles for social authentication (
social-auth
) and for working with images. -
Styles for the list of users (
#people-list
), including profile pictures and information about users. -
Styles for actions (
actions
), including date information.
This base.css
file provides base styles for templates and provides a consistent look and feel for pages in the "account" application. Other HTML templates that extend this base template can override and extend these styles for specific needs.
The admin.py
file from the actions
application defines the administrative interface settings for the Action
model. Here is what it does:
-
from django.contrib import admin
: This line imports theadmin
module from Django, which provides the admin interface functionality. -
from .models import Action
: This line imports theAction
model from the current "actions" application. -
@admin.register(Action)
: This decorator registers theAction
model in the Django admin interface. This means that theAction
model will be displayed and edited in the admin panel. -
class ActionAdmin(admin.ModelAdmin)
: This is the class that defines the administrative interface settings for theAction
model. It inherits fromadmin.ModelAdmin
, which allows you to customize the display and behavior of the model in the admin panel. -
list_display
: This attribute specifies which fields of theAction
model will be displayed in the list of records in the admin panel. In this case, the fields 'user', 'verb', 'target' and 'created' are displayed. -
list_filter
: This attribute adds filters to the sidebar of the admin panel, allowing administrators to filter records based on the 'created' (creation date) field. -
search_fields
: This attribute adds a search field at the top of the admin panel, allowing administrators to search for records by the 'verb' field.
These settings allow administrators to manage the Action
model in the Django admin panel, displaying the fields they want, providing filters and searches for easy data manipulation.
The apps.py
file from the "actions" application defines the configuration of the "actions" application. Here is what it does:
-
from django.apps import AppConfig
: This line imports theAppConfig
class from thedjango.apps
module. -
class ActionsConfig(AppConfig)
: This class represents the "actions" application configuration and inherits fromAppConfig
. -
default_auto_field = 'django.db.models.BigAutoField'
: This line sets the value of thedefault_auto_field
attribute to'django.db.models.BigAutoField'
. This specifies that when creating new models, Django should use the automatic large number field to auto-increment IDs. -
name = 'actions'
: This line sets the value of thename
attribute to'actions'
. This defines the name of the application, which will be used to identify it in the Django project.
In general, this apps.py
file defines the configuration of the "actions" application and sets the value of the default_auto_field
attribute, which determines what type of auto-increment field will be used when creating new models in this application.
The models.py
file from the "actions" application defines the Action
model, which represents the actions of users in the system. Here is what it does:
-
from django.db import models
: This line imports classes and functions for working with the database from thedjango.db
module. -
from django.contrib.contenttypes.models import ContentType
: This line imports theContentType
model fromdjango.contrib.contenttypes.models
.ContentType
is used to represent the types of models in the database. -
from django.contrib.contenttypes.fields import GenericForeignKey
: This line imports theGenericForeignKey
field fromdjango.contrib.contenttypes.fields
.GenericForeignKey
allows you to create relationships with different models using a generic key. -
class Action(models.Model)
: This class represents anAction
model for recording user actions. -
Fields of the
Action
model:user
: A foreign key that associates the action with a specific user (theUser
model fromauth
). Therelated_name
parameter is specified, which allows you to access user actions through feedback.verb
: A text field with a maximum length of 255 characters that contains a description of the action.created
: A date and time field that automatically sets the current time when the entry is created.target_ct
: A foreign key that associates the action with a specific model type (theContentType
model). May be empty (null=True
) and optional (blank=True
).target_id
: A field containing the ID of the model object that the action is associated with. It can also be empty (null=True
) and optional (blank=True
).target
: A generic foreign key that associates an action with a specific model object. Usestarget_ct
andtarget_id
to define a link to a specific model object.
-
class Meta
: This inner class defines the metadata for theAction
model.indexes
: Specifies indexes to improve performance when searching and filtering records. Here, indexes are set on thecreated
field and on thetarget_ct
andtarget_id
fields.ordering
: Specifies the default sorting of records in the result set. In this case, the entries are sorted in descending order by the creation date (created
).
The Action
model represents user actions in the system, such as recording that a user has performed a certain action, such as creating, deleting, commenting, etc. Foreign keys and generalized foreign keys allow actions to be associated with specific users and objects of various models.
The utils.py
file from the "actions" application contains the create_action
function, which creates a user action record. Here is what it does:
-
import datetime
: This module allows you to work with dates and times. -
from django.utils import timezone
: Django'stimezone
module provides utilities for working with timezones and times. -
from django.contrib.contenttypes.models import ContentType
: TheContentType
model fromdjango.contrib.contenttypes.models
is used to represent model types in the database. -
from .models import Action
: Import theAction
model from the current "actions" application. -
def create_action(user, verb, target=None)
: This is thecreate_action
function that creates a user action record with the given verb (verb
). The function takes parameters:user
: The user for which the action will be created.verb
: Text description of the action.target=None
: The target the action is associated with (optional, default isNone
).
-
now = timezone.now()
: Thenow
variable contains the current time zone. -
last_minute = now - datetime.timedelta(seconds=60)
: Thelast_minute
variable contains the time 60 seconds from the current time, i.e. previous minute. -
similar_actions = Action.objects.filter(user_id=user.id, verb=verb, created__gte=last_minute)
: A database query that retrieves all user action records with the given verb (verb
) created in the previous minute. -
if target:
: This condition checks if thetarget
parameter (target object of the action) is set. -
target_ct = ContentType.objects.get_for_model(target)
: Iftarget
is given, get the model type (ContentType
) for the target object. -
similar_actions = similar_actions.filter(target_ct=target_ct, target_id=target.id)
: Iftarget
is specified, then entries are additionally filtered by target object type and id. -
if not similar_actions:
: If no similar actions are found (actions taken by the same user with the same verb in the previous minute with the same target, if one is given), then the following code is executed:- A new entry is created in the
Action
model with the specified user, verb, and target (if given). - The record is stored in the database.
- A new entry is created in the
-
return True
: If a new entry was created, the function returnsTrue
. -
return False
: If no new record has been created (a similar action already exists), the function returnsFalse
.
Thus, the create_action
function is used to create records of user actions in the database and prevents duplicate records from being created if a similar action already exists.
The admin.py
file from the images
application contains the ImageAdmin
class, which defines the settings for the Django admin interface (Django Admin) for the Image
model. Here is what it does:
-
from django.contrib import admin
: This line imports theadmin
module from Django, which provides the functionality to create an admin interface. -
from .models import Image
: This line imports theImage
model from the current "images" application. -
@admin.register(Image)
: This decorator registers theImageAdmin
class with the admin interface for theImage
model. -
class ImageAdmin(admin.ModelAdmin)
: This class defines the administrative interface settings for theImage
model. -
Fields of the
ImageAdmin
class:list_display
: Specifies which model fields will be displayed in the list of objects in the admin interface. In this case, thetitle
,slug
,image
andcreated
fields will be displayed in the list of objects.list_filter
: Specifies which fields can be used to filter objects in the admin interface. In this case, objects can be filtered by thecreated
field (creation date).
Thus, the ImageAdmin
class determines which fields of the Image
model will be displayed in the list of objects and which fields will be available for filtering in the Django administrative interface.
The apps.py
file from the "images" application contains the ImagesConfig
class, which is configured as the configuration class for the "images" application in Django. Here is what it does:
-
from django.apps import AppConfig
: This line imports theAppConfig
class from Django, which provides the base configuration for the application. -
class ImagesConfig(AppConfig)
: ThisImagesConfig
class is a subclass ofAppConfig
and represents the configuration for the "images" application. -
default_auto_field = 'django.db.models.BigAutoField'
: This option specifies that when creating a new model in the "images" application, a field of typeBigAutoField
will be used as the primary key (field for auto-increment value). -
name = 'images'
: This is the application name "images". Django uses this name to identify and locate the application in the project. -
def ready(self)
: This is aready
method that is overridden from theAppConfig
base class. This method is executed when the application is loaded and is used to configure the application. -
import images.signals
: Inside theready
method, theimages.signals
module is imported. This means that when the "images" application is loaded, the code found in thesignals.py
file from the same application will be executed. Signals in Django allow you to associate certain actions with model events, such as creating, updating, or deleting records, and perform certain actions in response to those events.
Thus, the ImagesConfig
class provides the base configuration for the "images" application and runs code from the signals.py
file that can be executed when the application is loaded.
The forms.py
file from the "images" application contains the ImageCreateForm
class, which defines a form for creating new Image
model objects. Here is what it does:
-
from django import forms
: This line imports theforms
module from Django, which contains classes for working with forms. -
from .models import Image
: This line imports theImage
model from the current "images" application. -
from django.core.files.base import ContentFile
: This line imports theContentFile
class from Django, which represents the contents of a file. -
from django.utils.text import slugify
: This line imports theslugify
function from Django, which converts a string into a URL-like format. -
class ImageCreateForm(forms.ModelForm)
: ThisImageCreateForm
class is a subclass offorms.ModelForm
and represents a form for creatingImage
model objects. -
class Meta
: This nestedMeta
class defines the form's metadata.model = Image
: Indicates that the form is associated with theImage
model.fields = ['title', 'url', 'description']
: Specifies which model fields will be displayed in the form.widgets
: Allows you to set up widgets to display fields on the form. In this case, the 'url' field is used as a hidden field (HiddenInput
) that is not visible to the user.
-
def clean_url(self)
: This is theclean_url
method that checks and cleans the 'url' field data.- Gets the 'url' value from the cleared form data.
- Checks that the file extension extracted from the URL matches valid extensions ('jpg', 'jpeg', 'png').
- If the extension is not in the list of valid extensions, a
forms.ValidationError
exception is thrown.
-
def save(self, force_insert=False, force_update=False, commit=True)
: This is thesave
method, which is overridden from theforms.ModelForm
base class.- Calls the
save
method of the parent class to create theImage
model object. - Gets the value of the 'url' field from the cleared form data.
- Generates a filename based on the image title (
title
) and file extension from the URL. - Gets image content from URL using
requests
module. - Stores the image in the
image
field of theImage
model object. - If the parameter is
commit=True
, then saves theImage
model object to the database.
- Calls the
Thus, the ImageCreateForm
class provides a form for creating Image
model objects, including validating and saving the image obtained from the specified URL.
The models.py
file from the "images" application contains the Image
model, which represents image objects. Here is what it does:
-
from django.db import models
: This line imports themodels
module from Django, which provides database functionality. -
from django.conf import settings
: This line imports thesettings
module from Django to access the project settings. -
from django.utils.text import slugify
: This line imports theslugify
function from Django, which converts a string into a URL-like format. -
from django.urls import reverse
: This line imports thereverse
function from Django, which allows you to get the URL for a particular view. -
class Image(models.Model)
: ThisImage
class defines an image model. -
Fields of the
Image
class:user
: Field of type ForeignKey, associates the image with the user who created the image. Setson_delete=models.CASCADE
so that when the user is deleted, the images are also deleted.title
: A CharField that represents the title of the image and has a length limit of 200 characters.slug
: A field of type SlugField representing a URL-like unique identifier for the image. Left blank if not specified by the user, and populated automatically from the image title on save.url
: A field of type URLField that stores the URL of the image.image
: A field of type ImageField that stores the image itself and specifies the path to upload files to theimages/%Y/%m/%d/
directory.description
: A field of type TextField, designed to store a description of the image. May be empty.created
: A field of type DateField, automatically populated with the current date when the object is created.users_like
: A field of type ManyToManyField, links the image to users who haveliked
it using a many-to-many relationship (ManyToMany
).total_likes
: A field of type PositiveIntegerField, representing the total number of likes for the image. Set to 0 by default.
-
Nested
Meta
class: Defines model metadata.indexes
: Specifies indexes for query optimization. In this case, there are indexes for thecreated
andtotal_likes
fields.ordering
: Specifies the sorting of model objects. In this case, objects are sorted by creation date in descending order.
-
Image
class methods:__str__(self)
: A method that returns a string representation of an object. In this case, it returns the title of the image.save(self, *args, **kwargs)
: A method that overrides the standardsave
method to automatically populate theslug
field when the object is saved. Uses theslugify
function to generate a unique URL-like identifier from an image header.get_absolute_url(self)
: A method that returns an absolute URL to display the details of a particular image. Thereverse
function is used to get a URL based on the URL pattern name and theself.id
andself.slug
arguments.
Thus, the Image
class represents an image model that stores information about uploaded images, associated users, their "likes" and creation date.
The signals.py
file from the images
application contains signals that respond to changes in the Image
model, namely to changes in the users_like
field associated with image 'likes'. Here is what it does:
-
from django.db.models.signals import m2m_changed
: This line imports them2m_changed
signal, which is used to track changes in many-to-many (ManyToMany) relationship fields in models. -
from django.dispatch import receiver
: This line imports thereceiver
decorator, which is used to register the function as a signal handler. -
from .models import Image
: This line imports theImage
model from the current application. -
@receiver(m2m_changed, sender=Image.users_like.through)
: This decorator registers theusers_like_changed
function as anm2m_changed
signal handler for theImage.users_like.through
model. Them2m_changed
signal will be fired when there is a change in theusers_like
association forImage
model objects. -
def users_like_changed(sender, instance, **kwargs)
: This is them2m_changed
signal handler function. It will be called every time there is a change in the "likes" (users_like
) association of theImage
model. -
Inside the function:
instance.total_likes = instance.users_like.count()
: Updates thetotal_likes
field of theImage
object with the current number of users who have "liked" the image.instance.users_like.count()
returns the number of associated users.instance.save()
: Saves changes to theImage
object to update the value oftotal_likes
in the database.
Thus, these signals handle changes in the likes association for Image
model objects and automatically update the value of total_likes
to reflect the total number of likes for each image.
The urls.py
file from the "images" application defines URL patterns for the views of this application. Here is what it does:
-
from django.urls import path
: This line imports thepath
function from Django, which is used to define URL patterns. -
from . import views
: This line imports theviews
module from the current application to access the views that handle requests. -
app_name = 'images'
: This variable defines the application namespace for URL patterns. -
urlpatterns
: This list defines URL patterns and associates them with the corresponding views.path('create/', views.image_create, name='create')
: This URL pattern handles requests tocreate/
. It is associated with theimage_create
view, which will handle requests to create a new image. The name of the URL pattern is set to'create'
so that it can be referred to by name in templates or in code.path('detail/<int:id>/<slug:slug>/', views.image_detail, name='detail')
: This URL pattern handles requests todetail/<int:id>/<slug:slug>/
. It binds to theimage_detail
view, which will display the details of a specific image based on its id (id
) and URL-like id (slug
). The name of the URL pattern is set to'detail'
.path('like/', views.image_like, name='like')
: This URL pattern handles requests tolike/
. It binds to theimage_like
view, which will handle requests to "like" the image. The name of the URL pattern is set to'like'
.path('', views.image_list, name='list')
: This URL pattern handles requests at the root address (e.g./
). It is associated with theimage_list
view, which will display a list of all available images. The name of the URL pattern is given as'list'
.path('ranking/', views.image_ranking, name='ranking')
: This URL pattern handles requests toranking/
. It is associated with theimage_ranking
view, which will display the ranking of images based on the number of "likes". The name of the URL pattern is given as'ranking'
.
Thus, the urls.py
file defines URL patterns for creating, viewing details, liking images, as well as displaying a list of all images and rating.
The views.py
file from the "images" application contains views for query processing and data visualization. Here is what it does:
-
from django.shortcuts import render, redirect
: Imports therender
andredirect
functions from Django, which are used to render templates and redirect users. -
from django.contrib.auth.decorators import login_required
: Imports thelogin_required
decorator, which requires the user to be authenticated before the view is executed. -
from django.contrib import messages
: Imports themessages
function, which is used to send messages to the user. -
from django.shortcuts import get_object_or_404
: Imports theget_object_or_404
function, which allows you to get an object from the database or throw a 404 error if the object is not found. -
from django.http import JsonResponse, HttpResponse
: Imports theJsonResponse
andHttpResponse
classes, which are used to send a JSON response and a text response, respectively. -
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
: Imports thePaginator
,EmptyPage
andPageNotAnInteger
classes, which are used to paginate a list of images. -
from .forms import ImageCreateForm
: Imports theImageCreateForm
form from the current application. -
from .models import Image
: Imports theImage
model from the current application. -
from actions.utils import create_action
: Imports thecreate_action
function from the "actions" application. -
r = redis.Redis(host=settings.REDIS_HOST, port=settings.REDIS_PORT, db=settings.REDIS_DB)
: Creates a Redis connection using the settings from the project settings. -
Submissions:
-
image_create(request)
: Handles requests to create a new image. If the POST request and the form is valid, saves the image to the database and creates the corresponding "bookmarked image" activity. If the image was created successfully, redirects the user to the image details page. If the request is a GET method, displays a form to create an image. Thelogin_required
decorator is used to require user authentication to access the view. -
image_detail(request, id, slug)
: Handles requests to view the details of a specific image. Increments the image's view counter and displays information about the image and the number of views. -
image_like(request)
: Handles requests to like or unlike an image. Updates the user-like relationship for the image and creates the corresponding "likes" activity. Returns a JSON response with the result of the operation. -
image_list(request)
: Handle requests to display a list of all available images. Paginates the results and displays them on a scrollable page. -
image_ranking(request)
: Handles requests to display image ranking based on number of views. Gets data from Redis, sorts images by rating, and displays them on the page.
-
Thus, the views.py
file defines the views that handle user requests to create, view, like, and rank images.
The asgi.py
file from the "bookmarks" application is configured to work with ASGI (Asynchronous Server Gateway Interface) servers such as Daphne or uvicorn, which provide asynchronous request processing and allow Django applications to take advantage of asynchronous execution capabilities.
-
import os
: Imports theos
module, which provides functions for working with the operating system, such as setting environment variables. -
from django.core.asgi import get_asgi_application
: Imports theget_asgi_application
function from Django, which creates and returns an ASGI application object. -
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'bookmarks.settings')
: Sets the value of the environment variableDJANGO_SETTINGS_MODULE
to'bookmarks.settings'
, indicating that the "bookmarks" project settings are in thesettings.py
file. -
application = get_asgi_application()
: Creates an ASGI application using theget_asgi_application()
function and assigns it to theapplication
variable.
This file does nothing more than create an ASGI application, which can then be run by an ASGI-compliant server to process asynchronous requests to the "bookmarks" application.
The settings.py
file from the "bookmarks" application contains the Django settings for the "social network" project. This file defines database settings, security settings, language and time settings, paths to static and media files, and other settings necessary for the application to work properly.
Some of the key settings:
-
BASE_DIR
: Path to the project's root directory. -
DEBUG
: Indicates whether debug mode is enabled (True) or not (False). -
ALLOWED_HOSTS
: A list of allowed hosts that the application can run on. -
INSTALLED_APPS
: List of installed applications. -
MIDDLEWARE
: A list of middleware that handles requests and responses. -
DATABASES
: Database settings for the project. -
STATIC_URL
: URL prefix for static files. -
DEFAULT_AUTO_FIELD
: The field type for the auto primary key field. -
LOGIN_REDIRECT_URL
: The URL to which the user will be redirected after a successful login. -
LOGIN_URL
: URL for the login page. -
LOGOUT_URL
: URL for the logout page. -
MEDIA_URL
: URL prefix for media files. -
MEDIA_ROOT
: Path to directory where media files will be stored. -
AUTHENTICATION_BACKENDS
: List of authentication backends. -
SOCIAL_AUTH_*
: Settings for authentication through third party services (eg Twitter, Google). -
REDIS_HOST
,REDIS_PORT
,REDIS_DB
: Settings for connecting to the Redis server, which is used for caching and other asynchronous operations.
These are just some of the basic settings contained in the settings.py
file. All of these settings affect the behavior and functionality of a Django application within the "social network" project.
The urls.py
file from the "bookmarks" application contains the definition of URL patterns for the application. Here, requests are routed to the appropriate views (views) for processing requests and generating responses.
-
path('admin/', admin.site.urls)
: URL pattern to access the Django admin panel. -
path('account/', include('account.urls'))
: URL template for handling requests to the "account" application. All requests starting with '/account/' are passed to theurls.py
file of the "account" application for further processing. -
path('social-auth/', include('social_django.urls', namespace='social'))
: URL template for handling requests to the "social_django" application. All requests starting with '/social-auth/' are passed to theurls.py
file of the "social_django" application for further processing. -
path('images/', include('images.urls', namespace='images'))
: URL template for handling requests to the "images" application. All requests starting with '/images/' are passed to theurls.py
file of the "images" application for further processing. -
path('__debug__/', include('debug_toolbar.urls'))
: URL template for handling requests to the Django Debug Toolbar. All requests starting with '/debug/' are passed to theurls.py
file of the debug panel for further processing. -
if settings.DEBUG: urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
: Add a URL pattern for processing media files in debug mode. If DEBUG is set to True (debug mode), then a URL pattern is added to serve the media files specified in theMEDIA_URL
andMEDIA_ROOT
settings.
Thus, this urls.py
file determines which requests will be routed to the appropriate applications and views for processing. They are all combined into a common list of urlpatterns, which will be used by Django to determine which view to call when a particular request is received.
The wsgi.py
file from the "bookmarks" application is for running a Django application on a web server that supports WSGI (Web Server Gateway Interface). WSGI is an interface standard between Python web applications and web servers.
The following happens in the wsgi.py
file:
-
import os
: Importing theos
module to work with the operating system. -
from django.core.wsgi import get_wsgi_application
: Importing theget_wsgi_application
function from thedjango.core.wsgi
module, which returns a WSGI-compatible Django application. -
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'bookmarks.settings')
: Sets the environment variableDJANGO_SETTINGS_MODULE
with the path to the Django settings file for this application ("bookmarks.settings"). -
application = get_wsgi_application()
: Get a WSGI compatible Django application using theget_wsgi_application()
function and store it in theapplication
variable. This application will be used by the web server to process incoming HTTP requests and generate responses.
When the web server receives a request from a client (such as a browser), it calls the application
function in wsgi.py
, passing it information about the request. Django then processes the request, calls the appropriate view to form the response, and returns it back to the web server, which passes the response back to the client.
The requirements.txt
file contains a list of packages (along with their versions) that must be installed for the project or application to work. This is used in conjunction with Python dependency management tools such as pip
to automatically install all required packages.
When a developer wants to deploy a project on a new system, or make sure all dependencies are correctly installed on another machine, he can use the requirements.txt
file.
The pip install -r requirements.txt
command will automatically install all the listed packages and their versions.
In this case, the requirements.txt
file points to the following packages and their versions:
- Django and its dependencies, including
asgiref
,sqlparse
,urllib3
,idna
, and others. - Additional Django packages such as
django-debug-toolbar
,easy-thumbnails
,social-auth-app-django
, anddjango-extensions
. - Image packages such as
Pillow
,svglib
,reportlab
, and others. - Packages for dealing with authorization and OAuth, such as
oauthlib
,PyJWT
, andrequests-oauthlib
. - Other dependencies such as
cffi
,cryptography
,redis
, and others.
Each line in the file represents one package, with its name and version separated by two equal signs "==".
The "Social network" project uses several third-party libraries that greatly facilitate development and provide additional functionality. Here is a brief overview of the libraries used:
-
Django (4.1.10): Django is a high-level Python web framework that simplifies the creation of web applications and websites. It provides many out-of-the-box tools and modules for working with databases, authentication, templates, URLs, and other web application components.
-
django-debug-toolbar (3.6.0): This library provides a debug toolbar for Django that helps developers track and analyze queries, view SQL queries, profile views, and more. It is especially useful when developing and optimizing a project.
-
easy-thumbnails (2.8.1): This library provides an easy way to process and create image thumbnails. It allows you to automatically resize images, create different versions of thumbnails, and cache them to improve performance.
-
social-auth-app-django (5.2.0) and social-auth-core (4.4.2): These libraries provide authentication support through third party social networks such as Twitter and Google. They simplify the process of integrating social media authentication into an application, allowing users to log into the site using their social media accounts.
-
redis (4.3.4): Redis is an open source data store used by the project to support features such as image view and rating tracking. In this project, Redis is used to manage counters and sorted datasets.
-
requests (2.28.1): The requests library is used to send HTTP requests to third party servers. In this project, it is used to get images by URL and other HTTP requests.
-
django-extensions (3.2.3): This library adds additional tools and commands to make Django development easier, such as the
shell_plus
command, which automatically imports all models into the Django shell. -
lxml (4.9.3): Lxml is a library for handling XML and HTML. It is used to parse and process web pages and data in XML and HTML formats.
-
Pillow (9.2.0): Pillow is a fork of the Python Imaging Library (PIL) that provides imaging tools. In this project, Pillow is used to process and save uploaded images.
-
urllib3 (1.26.16): The urllib3 library is used to work with HTTP requests in Python. This project uses it along with the requests library to send HTTP requests.