PrasBridge: Simplify project development with a powerful toolkit for integrating SQLAlchemy with Django-style features. Offers serializers, enhanced forms, token generation, hashing, ready-to-use base models and more features. perfect for projects using SQLAlchemy as the main ORM.
Project description
PrasBridge
About
PrasBridge is a powerful Python package that seamlessly integrates Django and SQLAlchemy, providing enhanced form handling, serialization capabilities, and utility functions for building robust web applications.
Features
- 🔄 Seamless Django and SQLAlchemy Integration
- 📝 Enhanced Form Fields with Extra Functionality
- 🔐 Built-in Authentication Forms
- 🎨 Customizable Form Rendering
- 📦 Flexible Model Serialization
- 🛠️ Utility Functions (Token Generation, Slugify)
- 💼 Session Management
- 🏷️ Custom Template Tags
Installation
pip install PrasBridge
Quick Start
1. Configure Database Connection
# settings.py
DATABASES = {
'sqlalchemy': {
'URL': 'your-database-url-here'
}
}
2. Config Installed App
# settings.py
INSTALLED_APPS = [
...
'pras',
]
3. Create Models
# models.py
from pras.models import PrasBase, BaseUser
class User(BaseUser):
__tablename__ = 'users'
# Additional fields can be added here
...
4. Form Handling
from pras.forms import CharField, EmailField, RegistrationForm
class CustomRegistrationForm(RegistrationForm):
bio = CharField(max_length=500, required=False)
website = CharField(max_length=200, required=False)
def __init__(self, *args, **kwargs):
super().__init__(model=User, *args, **kwargs)
5. Template Tags
{% load pras %}
<form method="post">
{% csrf_token %}
{% pInput "username" form=form label=True error=True %}
{% pInput "email" form=form InputClass="custom-input" %}
{% pInput "password" form=form type="password" %}
<button type="submit">Submit</button>
</form>
Detailed Features
Base Models
PrasBridge provides robust base models designed to streamline essential fields for various classes, supporting extensibility and ease of use in applications.
PrasBase
PrasBase
is a foundational model for any entity that requires automatic tracking of creation and modification timestamps. It includes the following fields:
id:
Auto-generated primary key for unique identification of each instance.created_at:
Automatically stores the date and time the instance was created.updated_at:
Tracks the date and time of the most recent update to the instance.
BaseUser
BaseUser
builds on PrasBase and provides a structured template for user models. It includes essential fields for managing user accounts and permissions:
username:
Unique identifier for each user.first_name:
User’s first name.last_name:
User’s last name.email:
User’s email address, typically also unique.password:
Stores the user’s hashed password.is_active:
Boolean indicating if the account is active.is_staff:
Boolean flag for administrative permissions.is_superuser:
Boolean flag for superuser permissions.date_joined:
Timestamp indicating when the user account was created.PrasBase:
Inheritsid
,created_at
, andupdated_at
fields fromPrasBase
.
These fields make BaseUser
an ideal base for user authentication and authorization in applications, with built-in fields for permissions and user management.
Example
from pras import PrasBase, BaseUser
# Custom user model inheriting from BaseUser for applications that require user profiles
class User(BaseUser):
__tablename__ = 'users'
# Additional fields and methods specific to User can be added here
...
# Example model for a library system
class Book(PrasBase):
__tablename__ = 'books'
title = Column(String, nullable=False)
author = Column(String, nullable=False)
isbn = Column(String, unique=True, nullable=False)
...
# Additional attributes and methods specific to Book can be defined here
Notes
Flexibility:
BothPrasBase
andBaseUser
provide a flexible base structure that you can extend to suit specific application needs.Consistency:
Utilizing these models ensures that essential fields likecreated_at
andupdated_at
are consistently applied across your application.Customizability:
By inheriting from these bases, additional fields can be seamlessly added to create tailored entities.
Enhanced Form Fields
PrasBridge provides a suite of enhanced form fields with customizable options for common field types, including:
CharField
EmailField
TextAreaField
ChoiceField
CheckboxField
DateField
IntegerField
Common Arguments
These arguments apply to all PrasBridge form fields, providing flexible customization for events, accessibility, and styling:
- Events:
onclick
,onfocus
,onblur
,onchange
– JavaScript functions for handling user interactions. - Attributes:
required
,disabled
,readonly
,autocomplete
– Common HTML attributes for form fields. - Styling and Classes:
classes
,style
,id
– Options to add CSS classes, inline styles, and set a unique ID. - Display Options:
label
,label_suffix
,help_text
– Control label visibility, label suffix, and help text for field hints. - Field-Specific Options:
initial
,value
,show_hidden_initial
,localize
,validators
,data_attrs
,aria_attrs
– Set initial values, localize content, and add custom validation and data attributes.
Field Types
Each field type in PrasBridge includes arguments that are commonly defined using Django's attrs dictionary for widgets. PrasBridge fields offer these as direct arguments for ease of use.
CharField and EmailField
CharField
and EmailField
allow direct assignment of common attributes without defining them within attrs={}
.
-
Arguments
type (CharField only):
Field type, such as "text", "email", or "password".placeholder:
Placeholder text within the field.max_length / min_length:
Constraints on the length of input.title:
Tooltip text.size:
Size of the input field.strip:
Strips whitespace if True.empty_value:
Value if the field is empty.
-
Note
type
argument is only for CharFieldCharField
can be set toemail
type,EmailField
offers enhanced validation and error handling for email input.
-
Example
from pras.forms.fields import CharField, EmailField class MyForm(forms.Form): name = CharField( type="text", # text, email, or password placeholder="Enter your name", required=True, ... ) email = EmailField( placeholder="Enter your email", ... )
TextAreaField
PRAS’s TextAreaField
streamlines attribute customization, bypassing the need for attrs={}
.
-
Arguments
rows / cols:
Set the dimensions of the text area.placeholder:
Placeholder text for the field.max_length / min_length:
Limits on text length.size:
Size of the field.strip:
Strips whitespace if True.empty_value:
Value if the field is empty.
-
Example
from pras.forms.fields import TextAreaField class MyForm(forms.Form): bio = TextAreaField( rows=4, cols=50 ... )
ChoiceField
ChoiceField supports predefined options without needing a widget definition.
-
Arguments
choices:
List of tuple pairs representing value-label options.
-
Example
from pras.forms.fields import ChoiceField class MyForm(forms.Form): gender = ChoiceField( choices=[('Male', 'Male'), ('Female', 'Female')], ... )
CheckboxField
PRAS’s CheckboxField allows easy configuration of checked status.
-
Arguments
checked:
Boolean, if True, checkbox appears selected.
-
Example
from pras.forms.fields import CheckboxField class MyForm(forms.Form): agree = CheckboxField( checked=True, ... )
DateField
DateField supports date input with optional format validation.
-
Arguments
input_formats:
List of accepted date formats for validation.
-
Example
from pras.forms.fields import DateField class MyForm(forms.Form): birthdate = DateField( input_formats=["%Y-%m-%d"], ... )
IntegerField
IntegerField provides constraints and step control for numeric inputs.
-
Arguments
min_value / max_value:
Limits for accepted values.step:
Increment step size
-
Example
from pras.forms.fields import IntegerField class MyForm(forms.Form): age = IntegerField( min_value=18, max_value=100, step=1, ... )
Built-in Forms
PrasBridge Provides built-in forms for common authentication and registration.
- AuthenticationForm
- RegistrationForm
These forms handle the save functionality after cleaning and validating user input. However, both forms require a valid user model to function correctly—without one, they will raise an error. To use these forms, pass a valid model upon creation. If you need to modify the save functionality, you can override the save method.
Example
# forms.py
from pras.forms import AuthenticationForm, RegistrationForm
from pras.forms.fields import CharField
from .models import User
# Extending the AuthenticationForm
class MyAuthenticationForm(AuthenticationForm):
confirm_password = CharField(
type="password",
placeholder="Confirm password",
required=True
)
def __init__(self, *args, **kwargs):
# Pass a valid user model for `save` functionality
super().__init__(model=User, *args, **kwargs)
# views.py
from .forms import MyAuthenticationForm
from .models import User
from pras.forms import AuthenticationForm
def login(request):
# Custom form instance with a specified model
form = MyAuthenticationForm(
model=User, # Optional if the model is set in the form class
data=request.POST or None
)
# Alternatively, use the main AuthenticationForm without extending it
form = AuthenticationForm(model=User, data=request.POST or None)
if form.is_valid():
form.save() # Completes the login process with a valid User model
return render(request, 'login.html', {'form': form})
# Same for RegistrationForm also you need to pass a valid user model for `save` functionality like above
Note
-
The same usage applies for
RegistrationForm
as it does forAuthenticationForm
: Both forms require a valid user model to utilize the save functionality, whether you’re using them directly or extending them. -
Best Practice for Extending Forms: When extending
AuthenticationForm
,RegistrationForm
, or any other form within PRAS, it’s recommended to use the form fields provided by PrasBridge (CharField
,EmailField
, etc.) rather than Django’s built-in fields. These PrasBridge fields offer enhanced functionality with common arguments that streamline the configuration of attributes, keeping the implementation consistent with the PrasBridge other features. Additionally, PrasBridge’s fields are essential for compatibility with other PrasBridge-specific features, such as custom tags, ensuring seamless integration and 100% compatibility across all functionalities.
Serialization
PrasBridge provides flexible serialization options for your models:
Key Concepts
-
Serialization Prefix: Use a specific prefix when defining serialization schemas. For example, use
PRAS_
as the prefix for your schemas, such asPRAS_BasicInfo
. -
Identifier Field: The identifier field is crucial for defining serialization schemas. This unique field allows you to access the serialized data from the model using the
to_dict
method. You must pass the identifier toto_dict
to serialize the data according to the specified schema. -
Fields: The
fields
attribute is used to define which fields to serialize. It accepts three types of patterns:__all__
: Includes all fields. (default).username
: Serializes and returns only theusername
field data.!field_name
: Excludes the specified field from serialization. For example, use!password
to exclude the password field.
Example
from pras.models import BaseUser
class User(BaseUser):
__tablename__ = 'users'
# Define fields for the model
# Define serialization schemas
class PRAS_AllInfo:
__identifier__ = 'allinfo'
fields = ['__all__'] # Returns all data of the model
class PRAS_UsernameInfo:
__identifier__ = 'specific'
fields = ['username'] # Returns only the username field data
class PRAS_ExcludeInfo:
__identifier__ = 'exclude'
fields = ['!password'] # Returns all data except the password field
# Usage
user = User.query.first()
all_info = user.to_dict('allinfo') # All user data
username_info = user.to_dict('specific') # Only username data
exclude_info = user.to_dict('exclude') # All data except password
-
Serializing Related Models: To serialize related models, define a serialization pattern for related fields. For instance, if a model has a field
user = relationship(User)
, you need to specify the fields you wish to include.-
Supported Patterns:
__all__
: Include all fields of the related model.!field_name
: Exclude specified fields.field_name
: Include only that specific field.
-
Example
from pras.models import PrasBase, BaseUser
class User(BaseUser):
__tablename__ = 'users'
# Define fields for the user model
...
class Book(PrasBase):
__tablename__ = 'books'
user_id = Column(Integer, ForeignKey('users.id'))
user = relationship(User)
...
# Define serialization schema
class PRAS_BookInfo:
__identifier__ = 'bookinfo'
user = ['username', 'email'] # Returns only username and email of the related user named field
fields = ['__all__'] # Returns all data of the Book model
# Usage
book = Book.query.first()
book_info = book.to_dict('bookinfo') # Serializes book data along with specified user fields
Serializing Without PrasBase
or BaseUser
While PrasBase
and BaseUser
are designed for seamless integration with PrasBridge serialization features with SQLAlchemy, you can enable serialization for models that don’t use them by implementing the following:
from pras.serializers import PrasSerializer, IntegratedMeta # Import PrasSerializer and IntegratedMeta
from sqlalchemy.ext.declarative import declarative_base # Import SQLAlchemy's declarative base
Base = declarative_base(metaclass=IntegratedMeta) # Pass IntegratedMeta to sync PrasBridge serialization
class MyModel(Base, PrasSerializer): # Inherit Base and PrasSerializer
__tablename__ = 'users'
...
class PRAS_BookInfo:
__identifier__ = 'bookinfo'
fields = ['__all__']
Note
- The preferred approach is to use
PrasBase
andBaseUser
to ensure smooth integration with PRAS’s functionality. However, if you choose to use other base classes, you must manually enable the serialization feature with the above method.
Session Management
PRASAlchemy provides efficient session management with automatic transaction handling for SQLAlchemy sessions:
Key Concepts
session_scope
: A context manager that facilitates automatic transaction handling for SQLAlchemy sessions. It commits the session if no exceptions occur and rolls back the transaction if an exception is raised.get_session
: Returns a new session object for database operations.close
: Closes the specified session.
Usage
Using the Context Manager
from pras.session import SQLAlchemySessionManager
session_manager = SQLAlchemySessionManager()
with session_manager.session_scope() as session:
user = session.query(User).first()
user.email = "new@email.com"
# Automatically commits if no exception occurs; rolls back if an exception occurs.
Manual Session Management
from pras.session import SQLAlchemySessionManager
session_manager = SQLAlchemySessionManager()
session = session_manager.get_session()
try:
user = session.query(User).first()
user.email = "new@email.com"
session.commit() # Explicitly commit the session
except Exception as e:
session.rollback() # Rollback on exception
raise e
finally:
session_manager.close(session) # Ensure the session is closed
Tokenization
PrasBridge provides robust tokenization features for generating secure tokens and user-friendly slugs.
Token Generation
make_token
Argument | Type | Required | Default | Description |
---|---|---|---|---|
length |
int |
False |
32 |
The length of the generated token. |
numb |
bool |
False |
True |
Include numbers in the token. |
lower |
bool |
False |
True |
Include lowercase letters in the token. |
upper |
bool |
False |
True |
Include uppercase letters in the token. |
Example
from pras.hashers import make_token
# Generate a secure token with specified options
token = make_token(length=10, numb=False, lower=True, upper=True)
print(token) # Example output: 'aBcDeFgHiJ'
Slug Generation
slugify
Argument | type | Required | Default | Description |
---|---|---|---|---|
title |
str |
True |
None |
The title to be slugified. |
rand |
bool |
False |
False |
Add random string to the slug. |
rand_len |
int |
False |
10 |
Length of random string. |
dt |
bool |
False |
False |
Include current datetime in the slug. |
ms |
bool |
False |
False |
Include milliseconds in the slug. |
structure |
str |
False |
'title-rand' |
Structure of the slug (order of elements). |
sep |
str |
False |
'-' |
Separator used in the slug. |
case |
bool |
False |
False |
Preserve the original case of the title ; if False , convert to lowercase. |
spchar |
bool |
False |
False |
Include special characters in the slug. |
Example
from pras.hashers import slugify
# Basic slug generation
slug = slugify("My Blog Post") # Result: 'my-blog-post'
# Advanced slug generation with multiple options
slug = slugify(
"My Blog Post",
rand=True, # Add random string
rand_len=10, # Length of random string
dt=True, # Add current datetime
ms=True, # Include milliseconds
structure='title-dt-rand-ms', # Define slug structure
sep='-', # Use '-' as separator
case=True, # Preserve original case
spchar=False # Exclude special characters
)
print(slug) # Example output: 'My-Blog-Post-20241028-142837-KtFf1-RFAAa-1730104117955'
Template Tags
PrasBridge provides a set of template tags to easily render forms and input fields with customizable options.
pInput
Renders a specific input field with customizable options.
Attribute | Type | Expected | Required | Default | Description |
---|---|---|---|---|---|
field_name |
str |
any |
True |
None |
The name of the form field. |
form |
Form |
any |
False |
form |
The form instance where the input field is stored. |
html |
str |
any |
False |
None |
Custom HTML code to render in the label tag. |
Class |
str |
any |
False |
None |
CSS class for the main container. |
style |
str |
any |
False |
None |
CSS styles for the input field. |
LabelClass |
str |
any |
False |
None |
CSS class for the label tag. |
InputClass |
str |
any |
False |
None |
CSS class for the input field. |
ErrorClass |
str |
any |
False |
None |
CSS class for the error message. |
label |
bool |
true or false |
False |
true |
Whether to render the label. |
error |
bool |
true or false |
False |
true |
Whether to render the error message. |
defaultEv |
bool |
true or false |
False |
true |
Disable default behaviors if set to False . |
placeholder |
str |
any |
False |
None |
Placeholder text for the input field. |
LabelText |
str |
any |
False |
None |
Text to be displayed in the label. |
defaultValue |
str |
any |
False |
None |
Default value for the input field. |
Example
<!-- Load the PrasBridge template tags -->
{% load pras %}
<!-- Render an input field for email -->
{% pInput "email" -> field_name
form="form"
Class="wrapper-class"
InputClass="input-class"
LabelClass="label-class"
ErrorClass="error-class"
label="true"
error="true"
placeholder="Enter email"
LabelText="Custom Label"
%}
pForm
Renders the complete form with customizable options.
Attribute | Type | Expected | Required | Default | Description |
---|---|---|---|---|---|
form |
Form |
any |
False |
form |
The form instance to be rendered. |
method |
str |
any |
False |
'post' |
HTTP method for the form submission. |
action |
str |
any |
False |
None |
Action URL for form submission. |
Class |
str |
any |
False |
None |
CSS class for the main container. |
FormClass |
str |
any |
False |
None |
CSS class for the form element. |
InputClass |
str |
any |
False |
None |
CSS class for the input fields. |
id |
str |
any |
False |
None |
ID for the form element. |
ButtonLabel |
str |
any |
False |
'Submit' |
Label text for the submit button. |
ButtonClass |
str |
any |
False |
None |
CSS class for the submit button. |
LabelClass |
str |
any |
False |
None |
CSS class for label tags. |
ErrorClass |
str |
any |
False |
None |
CSS class for error messages. |
label |
bool |
true or false |
False |
true |
Whether to render labels for input fields. |
error |
bool |
true or false |
False |
true |
Whether to render error messages. |
defaultEv |
bool |
true or false |
False |
true |
Disable default behaviors if set to False |
Example
<!-- Load the PrasBridge template tags -->
{% load pras %}
<!-- Render a complete form -->
{% pForm "form"
method="post"
action="/submit"
Class="form-wrapper"
FormClass="form-class"
InputClass="input-class"
ButtonLabel="Submit"
ButtonClass="btn-class"
%}
Note
- To leverage the full functionality of these tags, it is recommended to use PrasBridge-provided form fields, as they synchronize more efficiently with PrasBridge template tags. While Django form fields are supported, using PrasBridge fields allows for greater customization and compatibility.
Best Practices
- Always use PrasBridge form fields instead of Django form fields for consistent styling and functionality.
- Use the session manager's context manager (
session_scope
) when possible for automatic transaction handling. - Define clear serialization schemas for different use cases.
- Utilize the built-in user authentication forms for standard user management.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Support
If you encounter any problems or have questions, please:
- Check the documentation
- Open an issue on GitHub
- Contact the maintainers
Credits
PRAS is maintained by PRASSamin and was created to simplify Django and SQLAlchemy integration while providing enhanced functionality for modern web applications.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.