Welcome to Eggplant’s documentation!¶
Contents:
Installation¶
TODO: Move from README.rst
Contributing¶
Contributions are welcome, and they are greatly appreciated! Every little bit helps, and credit will always be given.
You can contribute in many ways:
Types of Contributions¶
Report Bugs¶
Report bugs at https://github.com/kbhff/eggplant/issues.
If you are reporting a bug, please include:
- Your operating system name and version.
- Any details about your local setup that might be helpful in troubleshooting.
- Detailed steps to reproduce the bug.
Fix Bugs¶
Look through the GitHub issues for bugs. Anything tagged with “bug” is open to whoever wants to implement it.
Implement Features¶
Look through the GitHub issues for features. Anything tagged with “feature” is open to whoever wants to implement it.
Write Documentation¶
eggplant could always use more documentation, whether as part of the official eggplant docs, in docstrings, or even on the web in blog posts, articles, and such.
Submit Feedback¶
The best way to send feedback is to file an issue at https://github.com/kbhff/eggplant/issues.
If you are proposing a feature:
- Explain in detail how it would work.
- Keep the scope as narrow as possible, to make it easier to implement.
- Remember that this is a volunteer-driven project, and that contributions are welcome :)
Get Started!¶
Ready to contribute? Here’s how to set up eggplant for local development.
If you are completely new to source code versioning using git, please search for a video explaining it. And ask for help getting a git tool set up on your machine.
Note
We have decided to use the very conventional a simple git branching model. Read the guide to get a good introduction to Git workflows.
$ git clone git@github.com:kbhff/eggplant.git
Virtualenv¶
The project is pretty basic, these are classical just steps. Just make note that it’s a Python 3.4 only project. Enter the git project folder.
$ pip install virtualenvwrapper
To get the mkvirtualenv command you need to:
source /usr/local/bin/virtualenvwrapper.sh
On debian this file in:
/etc/bash_completion.d/virtualenvwrapper
start a new bash session to source it.
$ mkvirtualenv eggplantenv -p python3.4
$ workon eggplantenv
$ pip install -r requirements/development.txt
$ python manage.py syncdb
$ python manage.py runserver
Use “workon eggplantenv” to activate the eggplan virtual environment, and “deactivate” to exit.
This will deploy a local SQLite database and run a local webserver. If you are completely new to Django and Python, notice that you need [pip](https://pip.pypa.io/en/stable/installing.html), too.
Vagrant¶
(Optional) This takes some time (downloading) and some harddisk capacity.
Another way to get started contributing to this project is to download and install git and [Vagrant](http://vagrantup.com/), Clone the project (as mentioned above), change directory into the eggplant folder and then run the following commands:
$ vagrant up
$ vagrant ssh
$ python manage.py migrate
$ python manage.py test
$ python manage.py createsuperuser
$ python manage.py runserver
This will download and bootstrap an ubuntu 14.04 vagrant box, connect to it, start the django development server. The project should now be available at [http://192.168.33.28:8000/](http://192.168.33.28:8000/).
Pull Request Guidelines¶
Before you submit a pull request, check that it meets these guidelines:
- The pull request should include tests.
- If the pull request adds functionality, the docs should be updated. Put your new functionality into a function with a docstring, and add the feature to the list in README.rst.
- The pull request should work for Python 3.4. https://travis-ci.org/kbhff/eggplant/pull_requests and make sure that the tests pass for all supported Python versions.
Authors¶
Lots of people contributed to this group through the Eggplant Meetup group in Copenhagen.
Developer documentation¶
Component overview¶
The Eggplant application contains the following sub-applications (python packages
nested in eggplant/
containing models and migrations).
Applications inside eggplant/
are interdependent, except core
which
should not depend on anything else and permissions
which all other
applications are expected to use.
accounts
- Administration and user pages related to accounts, being everything that has to do with user’s transactions inside the market.core
- an application with models that all other applications may depend on, dependency of othersdashboard
- Functionality for workflow of members, administrators etc.departments
- Administration logic regarding a department such as shifts.invitations
- Sending of invitation emails to create new user profiles that join accounts, departments etc.membership
- Extends from Django allauth and contains the models of memberships and their organizations.market
- Contains everything related to paying for stuff, invoicing, and creating and managing goods such as grocery bags.permissions
- Models and decorators for permissions, dependency of othersprofiles
- User information
Coupling¶
Currently, we expect applications to depend on each other’s models. But it would get messy if templates, views, and static assets also started being interdependent.
Possible scheme: Only allow models and decorators to be interdependent, all
other common elements should live in eggplant.core
.
Philosophy¶
To quote Two Scoops of Django (1.8 version) that in turn quotes James Bennett (who in turn quotes Douglas McIlroy):
James Bennett volunteers as both a Django core developer and as its release manager. He taught us everything that we know about good Django app design. We quote him:
“The art of creating and maintaining a good Django app is that it should follow the truncated Unix philosophy according to Douglas McIlroy:
‘Write programs that do one thing and do it well.’In essence, each app should be tightly focused on its task. If an app can’t be explained in a single sentence of moderate length, or you need to say ‘and’ more than once, it probably means the app is too big and should be broken up.
TODO¶
The scope of the applications may need to be consolidated.
Dependency overview¶
askdasdk
Python Reference¶
eggplant package¶
Subpackages¶
eggplant.accounts package¶
Submodules¶
eggplant.accounts.admin module¶
-
class
eggplant.accounts.admin.
AccountAdmin
(model, admin_site)[source]¶ Bases:
django.contrib.admin.options.ModelAdmin
-
inlines
= [<class 'eggplant.accounts.admin.AccountMembershipInline'>]¶
-
media
¶
-
eggplant.accounts.models module¶
-
class
eggplant.accounts.models.
Account
(id, name, category, department, start, exit, active)[source]¶ Bases:
django.db.models.base.Model
-
exception
DoesNotExist
¶ Bases:
django.core.exceptions.ObjectDoesNotExist
-
exception
Account.
MultipleObjectsReturned
¶ Bases:
django.core.exceptions.MultipleObjectsReturned
-
Account.
category
¶
-
Account.
department
¶
-
Account.
get_next_by_start
(*moreargs, **morekwargs)¶
-
Account.
get_previous_by_start
(*moreargs, **morekwargs)¶
-
Account.
objects
= <django.db.models.manager.Manager object>¶
-
Account.
payment_set
¶
-
Account.
user_profiles
¶
-
Account.
userprofilepermission_set
¶
-
exception
-
class
eggplant.accounts.models.
AccountCategory
(id, name)[source]¶ Bases:
django.db.models.base.Model
-
exception
DoesNotExist
¶ Bases:
django.core.exceptions.ObjectDoesNotExist
-
exception
AccountCategory.
MultipleObjectsReturned
¶ Bases:
django.core.exceptions.MultipleObjectsReturned
-
AccountCategory.
accounts
¶
-
AccountCategory.
departmentinvitation_set
¶
-
AccountCategory.
objects
= <django.db.models.manager.Manager object>¶
-
exception
eggplant.accounts.tests module¶
eggplant.accounts.urls module¶
eggplant.accounts.views module¶
Module contents¶
eggplant.core package¶
Subpackages¶
Break a list into
n
pieces. The last list may be larger than the rest if the list doesn’t break cleanly. That is:>>> l = range(10) >>> partition(l, 2) [[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]] >>> partition(l, 3) [[0, 1, 2], [3, 4, 5], [6, 7, 8, 9]] >>> partition(l, 4) [[0, 1], [2, 3], [4, 5], [6, 7, 8, 9]] >>> partition(l, 5) [[0, 1], [2, 3], [4, 5], [6, 7], [8, 9]]
Break a list into
n
peices, but “horizontally.” That is,partition_horizontal(range(10), 3)
gives:[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
Submodules¶
eggplant.core.context_processors module¶
eggplant.core.tests module¶
eggplant.core.utils module¶
eggplant.core.views module¶
eggplant.core.widgets module¶
Module contents¶
eggplant.dashboard package¶
Submodules¶
eggplant.dashboard.admin module¶
eggplant.dashboard.models module¶
eggplant.dashboard.tests module¶
eggplant.dashboard.urls module¶
Dashboard urlconf, included by foodnet.urls
Final namespace of these URLs:
eggplant:dashboard:url_name
eggplant.dashboard.views module¶
Module contents¶
eggplant.departments package¶
Submodules¶
eggplant.departments.admin module¶
eggplant.departments.models module¶
-
class
eggplant.departments.models.
Department
(id, name, slug, site)[source]¶ Bases:
django.db.models.base.Model
-
exception
DoesNotExist
¶ Bases:
django.core.exceptions.ObjectDoesNotExist
-
exception
Department.
MultipleObjectsReturned
¶ Bases:
django.core.exceptions.MultipleObjectsReturned
-
Department.
accounts
¶
-
Department.
departmentadministrator_set
¶
-
Department.
departmentinvitation_set
¶
-
Department.
objects
= <django.db.models.manager.Manager object>¶
-
Department.
site
¶
-
Department.
userprofilepermission_set
¶
-
exception
-
class
eggplant.departments.models.
DepartmentAdministrator
(id, department, profile, created)[source]¶ Bases:
django.db.models.base.Model
-
exception
DoesNotExist
¶ Bases:
django.core.exceptions.ObjectDoesNotExist
-
exception
DepartmentAdministrator.
MultipleObjectsReturned
¶ Bases:
django.core.exceptions.MultipleObjectsReturned
-
DepartmentAdministrator.
department
¶
-
DepartmentAdministrator.
get_next_by_created
(*moreargs, **morekwargs)¶
-
DepartmentAdministrator.
get_previous_by_created
(*moreargs, **morekwargs)¶
-
DepartmentAdministrator.
objects
= <django.db.models.manager.Manager object>¶
-
DepartmentAdministrator.
profile
¶
-
exception
eggplant.departments.tests module¶
eggplant.departments.urls module¶
eggplant.departments.views module¶
-
class
eggplant.departments.views.
DepartmentProfiles
(**kwargs)[source]¶ Bases:
eggplant.core.views.LoginRequiredMixin
,django.views.generic.list.ListView
-
model
¶ alias of
UserProfile
-
paginate_by
= 25¶
-
template_name
= 'eggplant/departments/profiles.html'¶
-
-
eggplant.departments.views.
departments_profiles
(request, *args, **kwargs)¶
Module contents¶
eggplant.invitations package¶
Submodules¶
eggplant.invitations.admin module¶
eggplant.invitations.auth_backends module¶
eggplant.invitations.forms module¶
-
class
eggplant.invitations.forms.
AcceptInvitationForm
(data=None, files=None, auto_id=u'id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False)[source]¶ Bases:
django.forms.forms.Form
-
base_fields
= OrderedDict([('captcha', <captcha.fields.ReCaptchaField object at 0x7f4f598ccb50>)])¶
-
declared_fields
= OrderedDict([('captcha', <captcha.fields.ReCaptchaField object at 0x7f4f598ccb50>)])¶
-
media
¶
-
-
class
eggplant.invitations.forms.
DepartmentInvitationForm
(data=None, files=None, auto_id=u'id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False, instance=None)[source]¶ Bases:
django.forms.models.ModelForm
-
class
Meta
[source]¶ -
fields
= ['department', 'account_category', 'email']¶
-
model
¶ alias of
DepartmentInvitation
-
-
DepartmentInvitationForm.
base_fields
= OrderedDict([('department', <django.forms.models.ModelChoiceField object at 0x7f4f598cc610>), ('account_category', <django.forms.models.ModelChoiceField object at 0x7f4f598ccd10>), ('email', <django.forms.fields.EmailField object at 0x7f4f598cc510>)])¶
-
DepartmentInvitationForm.
declared_fields
= OrderedDict([('email', <django.forms.fields.EmailField object at 0x7f4f598cc510>)])¶
-
DepartmentInvitationForm.
media
¶
-
class
eggplant.invitations.models module¶
-
class
eggplant.invitations.models.
DepartmentInvitation
(id, email, accepted, accepted_at, verification_key, created, invited_by, department, account_category)[source]¶ Bases:
eggplant.invitations.models.InvitationBase
-
exception
DoesNotExist
¶ Bases:
django.core.exceptions.ObjectDoesNotExist
-
exception
DepartmentInvitation.
MultipleObjectsReturned
¶ Bases:
django.core.exceptions.MultipleObjectsReturned
-
DepartmentInvitation.
account_category
¶
-
DepartmentInvitation.
department
¶
-
DepartmentInvitation.
get_next_by_created
(*moreargs, **morekwargs)¶
-
DepartmentInvitation.
get_previous_by_created
(*moreargs, **morekwargs)¶
-
DepartmentInvitation.
invited_by
¶
-
DepartmentInvitation.
objects
= <django.db.models.manager.Manager object>¶
-
exception
eggplant.invitations.tests module¶
eggplant.invitations.urls module¶
eggplant.invitations.utils module¶
eggplant.invitations.views module¶
Module contents¶
eggplant.market package¶
Subpackages¶
-
class
eggplant.market.models.cart.
Basket
(id, user, created, status)[source]¶ Bases:
django.db.models.base.Model
-
CHECKEDOUT
= 'checked-out'¶
-
exception
DoesNotExist
¶ Bases:
django.core.exceptions.ObjectDoesNotExist
-
exception
Basket.
MultipleObjectsReturned
¶ Bases:
django.core.exceptions.MultipleObjectsReturned
-
Basket.
OPEN
= 'open'¶
-
Basket.
STATUES
= (('open', 'open'), ('checked-out', 'checked-out'))¶
-
Basket.
get_next_by_created
(*moreargs, **morekwargs)¶
-
Basket.
get_previous_by_created
(*moreargs, **morekwargs)¶
-
Basket.
get_status_display
(*moreargs, **morekwargs)¶
-
Basket.
items
¶
-
Basket.
objects
= <eggplant.market.models.cart.BasketManager object>¶
-
Basket.
user
¶
-
-
class
eggplant.market.models.cart.
BasketItem
(id, basket, product, quantity, delivery_date)[source]¶ Bases:
django.db.models.base.Model
-
exception
DoesNotExist
¶ Bases:
django.core.exceptions.ObjectDoesNotExist
-
exception
BasketItem.
MultipleObjectsReturned
¶ Bases:
django.core.exceptions.MultipleObjectsReturned
-
BasketItem.
basket
¶
-
BasketItem.
objects
= <django.db.models.manager.Manager object>¶
-
BasketItem.
product
¶
-
exception
-
class
eggplant.market.models.inventory.
Product
(id, title, description, category, price_currency, price, stock, tax, enabled, image)[source]¶ Bases:
django.db.models.base.Model
-
exception
DoesNotExist
¶ Bases:
django.core.exceptions.ObjectDoesNotExist
-
exception
Product.
MultipleObjectsReturned
¶ Bases:
django.core.exceptions.MultipleObjectsReturned
-
Product.
basketitem_set
¶
-
Product.
category
¶
-
Product.
get_price_currency_display
(*moreargs, **morekwargs)¶
-
Product.
image
¶ Just like the FileDescriptor, but for ImageFields. The only difference is assigning the width/height to the width_field/height_field, if appropriate.
-
Product.
objects
= <djmoney.models.managers.MoneyManager object>¶
-
Product.
price
¶
-
Product.
tax
¶
-
exception
-
class
eggplant.market.models.inventory.
ProductCategory
(id, title, description, enabled)[source]¶ Bases:
django.db.models.base.Model
-
exception
DoesNotExist
¶ Bases:
django.core.exceptions.ObjectDoesNotExist
-
exception
ProductCategory.
MultipleObjectsReturned
¶ Bases:
django.core.exceptions.MultipleObjectsReturned
-
ProductCategory.
objects
= <django.db.models.manager.Manager object>¶
-
ProductCategory.
product_set
¶
-
exception
-
class
eggplant.market.models.inventory.
ProductTax
(id, title, description, enabled, tax)[source]¶ Bases:
django.db.models.base.Model
-
exception
DoesNotExist
¶ Bases:
django.core.exceptions.ObjectDoesNotExist
-
exception
ProductTax.
MultipleObjectsReturned
¶ Bases:
django.core.exceptions.MultipleObjectsReturned
-
ProductTax.
objects
= <django.db.models.manager.Manager object>¶
-
ProductTax.
product_set
¶
-
exception
Notice: getpaid calls it “order” objects, however since our payments app does not model orders, we also call this “payment” in eggplant.payments.models
-
eggplant.market.models.listeners.
new_payment_listener
(sender, order=None, payment=None, **kwargs)[source]¶ Log how many and which payments were made.
-
eggplant.market.models.listeners.
new_payment_query_listener
(sender, order=None, payment=None, **kwargs)[source]¶ Fills in required payment details.
-
eggplant.market.models.listeners.
order_additional_validation_listener
(sender, request=None, order=None, backend=None, **kwargs)[source]¶ Custom validation.
-
class
eggplant.market.models.payment.
Payment
(id, amount_currency, amount, account, created)[source]¶ Bases:
django.db.models.base.Model
-
exception
DoesNotExist
¶ Bases:
django.core.exceptions.ObjectDoesNotExist
-
exception
Payment.
MultipleObjectsReturned
¶ Bases:
django.core.exceptions.MultipleObjectsReturned
-
Payment.
account
¶
-
Payment.
amount
¶
-
Payment.
get_amount_currency_display
(*moreargs, **morekwargs)¶
-
Payment.
get_next_by_created
(*moreargs, **morekwargs)¶
-
Payment.
get_previous_by_created
(*moreargs, **morekwargs)¶
-
Payment.
objects
= <djmoney.models.managers.MoneyManager object>¶
-
Payment.
payments
¶
-
exception
-
class
eggplant.market.views.cart.
BaseCartActionView
(**kwargs)[source]¶ Bases:
django.views.generic.edit.FormView
-
form_class
¶ alias of
BasketItemForm
-
success_url
= <django.utils.functional.__proxy__ object>¶
-
-
eggplant.market.views.cart.
add_to_cart
(request, *args, **kwargs)¶
-
eggplant.market.views.cart.
remove_from_cart
(request, *args, **kwargs)¶
-
class
eggplant.market.views.payment.
PaymentView
(**kwargs)[source]¶ Bases:
eggplant.core.views.LoginRequiredMixin
,django.views.generic.detail.DetailView
-
model
¶ alias of
Payment
-
template_name
= 'eggplant/market/payment_detail.html'¶
-
-
eggplant.market.views.payment.
payment_detail
(request, *args, **kwargs)¶
Submodules¶
eggplant.market.admin module¶
eggplant.market.filters module¶
-
class
eggplant.market.filters.
LinksGroupWidget
(attrs=None, choices=())[source]¶ Bases:
django_filters.widgets.LinkWidget
-
media
¶
-
option_string
()¶
-
render
(name, value, attrs=None, choices=())¶
-
render_option
(name, selected_choices, option_value, option_label)¶
-
-
class
eggplant.market.filters.
ProductFilter
(*args, **kwargs)[source]¶ Bases:
django_filters.filterset.FilterSet
-
ProductFilter.
base_filters
= OrderedDict([('category', <django_filters.filters.ModelChoiceFilter object at 0x7f4f5969ebd0>)])¶
-
ProductFilter.
declared_filters
= OrderedDict([('category', <django_filters.filters.ModelChoiceFilter object at 0x7f4f5969ebd0>)])¶
-
eggplant.market.forms module¶
-
class
eggplant.market.forms.
BasketItemForm
(data=None, files=None, auto_id=u'id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False)[source]¶ Bases:
django.forms.forms.Form
-
base_fields
= OrderedDict([('product', <django.forms.models.ModelChoiceField object at 0x7f4f59834e90>), ('quantity', <django.forms.fields.IntegerField object at 0x7f4f59834f50>), ('delivery_date', <django.forms.fields.DateField object at 0x7f4f59840210>)])¶
-
declared_fields
= OrderedDict([('product', <django.forms.models.ModelChoiceField object at 0x7f4f59834e90>), ('quantity', <django.forms.fields.IntegerField object at 0x7f4f59834f50>), ('delivery_date', <django.forms.fields.DateField object at 0x7f4f59840210>)])¶
-
media
¶
-
-
class
eggplant.market.forms.
ProductForm
(data=None, files=None, auto_id=u'id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False, instance=None)[source]¶ Bases:
django.forms.models.ModelForm
-
class
Meta
[source]¶ -
fields
= ['title', 'description', 'price', 'category', 'tax', 'stock']¶
-
model
¶ alias of
Product
-
widgets
= {'price': <eggplant.core.widgets.MoneyWidget object at 0x7f4f598403d0>}¶
-
-
ProductForm.
base_fields
= OrderedDict([('title', <django.forms.fields.CharField object at 0x7f4f598405d0>), ('description', <django.forms.fields.CharField object at 0x7f4f59840710>), ('price', <djmoney.forms.fields.MoneyField object at 0x7f4f5969e450>), ('category', <django.forms.models.ModelChoiceField object at 0x7f4f59840850>), ('tax', <django.forms.models.ModelChoiceField object at 0x7f4f5969e750>), ('stock', <django.forms.fields.IntegerField object at 0x7f4f5969e610>)])¶
-
ProductForm.
declared_fields
= OrderedDict()¶
-
ProductForm.
media
¶
-
class
eggplant.market.tests module¶
eggplant.market.urls module¶
Module contents¶
eggplant.permissions package¶
Submodules¶
eggplant.permissions.admin module¶
eggplant.permissions.models module¶
Permission philosophy:
- Be explicit! Uses boolean fields for specific tasks
- Be SQL friendly, create permissions that are nice to work with in query set lookups
- Put logic in decorators
-
class
eggplant.permissions.models.
Permission
(*args, **kwargs)[source]¶ Bases:
django.db.models.base.Model
Permission roles are a set of permissions. Permissions are modeled as booleans in this model.
What can a user do? Examples from discussion of different roles:
A user is a superuser: Don’t put it here – THIS IS FOR THE global User.is_superuser field!!
A user can create and manage all departments.: E.g. someone from the central commission can add a new department and close an existing one.
A user is a department manager: Can create and delete accounts and user profiles for everyone in a department.
A user is an “intro vagt”: Someone who can create new accounts
A user is a team link: Can manage volunteer shifts
A user owns an account: Can add credit card, can add others to the account
CONCEPT OF THIS MODEL: Create boolean fields for different permissions, create lots of them! We want to be very explicit.
-
exception
DoesNotExist
¶ Bases:
django.core.exceptions.ObjectDoesNotExist
-
exception
Permission.
MultipleObjectsReturned
¶ Bases:
django.core.exceptions.MultipleObjectsReturned
-
Permission.
objects
= <django.db.models.manager.Manager object>¶
-
Permission.
userprofile_set
¶
-
Permission.
userprofilepermission_set
¶
-
exception
-
class
eggplant.permissions.models.
UserProfilePermission
(*args, **kwargs)[source]¶ Bases:
django.db.models.base.Model
Link between a user profile and a set of permissions (a role).
Example 1:
Check if a user has user creation access to a department: can_add_users = department.userprofilepermission_set.filter( user_profile__user=request.user, permission__can_add_user_profiles=True ).exists() if can_add_users: obama_speech = "YES WE CAN" print(obama_speech) Example 2: Check if user can manage an account, like changing the data: can_change_account = account.userprofilepermission_set.filter( user_profile__user=request.user, permission__can_change_accounts=True, ) if not can_change_account: return HttpNotAllowed("piss off")
TODO: Create decorators to manage this easier!
-
exception
DoesNotExist
¶ Bases:
django.core.exceptions.ObjectDoesNotExist
-
exception
UserProfilePermission.
MultipleObjectsReturned
¶ Bases:
django.core.exceptions.MultipleObjectsReturned
-
UserProfilePermission.
account
¶
-
UserProfilePermission.
department
¶
-
UserProfilePermission.
objects
= <django.db.models.manager.Manager object>¶
-
UserProfilePermission.
permission
¶
-
UserProfilePermission.
user_profile
¶
-
exception
eggplant.permissions.tests module¶
Module contents¶
eggplant.profiles package¶
Submodules¶
eggplant.profiles.admin module¶
eggplant.profiles.forms module¶
-
class
eggplant.profiles.forms.
NewUserSetPasswordForm
(user=None, *args, **kwargs)[source]¶ Bases:
allauth.account.forms.SetPasswordForm
-
base_fields
= OrderedDict([('password1', <allauth.account.forms.SetPasswordField object at 0x7f4f59895c90>), ('password2', <allauth.account.forms.PasswordField object at 0x7f4f59895d90>)])¶
-
declared_fields
= OrderedDict([('password1', <allauth.account.forms.SetPasswordField object at 0x7f4f59895c90>), ('password2', <allauth.account.forms.PasswordField object at 0x7f4f59895d90>)])¶
-
media
¶
-
-
class
eggplant.profiles.forms.
ProfileForm
(data=None, files=None, auto_id=u'id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False)[source]¶ Bases:
django.forms.forms.Form
-
base_fields
= OrderedDict([('first_name', <django.forms.fields.CharField object at 0x7f4f5981e610>), ('middle_name', <django.forms.fields.CharField object at 0x7f4f5981e6d0>), ('last_name', <django.forms.fields.CharField object at 0x7f4f5981e790>), ('address', <django.forms.fields.CharField object at 0x7f4f5981e850>), ('city', <django.forms.fields.CharField object at 0x7f4f5981e910>), ('postcode', <django.forms.fields.CharField object at 0x7f4f5981e9d0>), ('tel', <django.forms.fields.CharField object at 0x7f4f5981ea90>), ('sex', <django.forms.fields.ChoiceField object at 0x7f4f5981eb50>), ('photo', <django.forms.fields.ImageField object at 0x7f4f5981ebd0>)])¶
-
declared_fields
= OrderedDict([('first_name', <django.forms.fields.CharField object at 0x7f4f5981e610>), ('middle_name', <django.forms.fields.CharField object at 0x7f4f5981e6d0>), ('last_name', <django.forms.fields.CharField object at 0x7f4f5981e790>), ('address', <django.forms.fields.CharField object at 0x7f4f5981e850>), ('city', <django.forms.fields.CharField object at 0x7f4f5981e910>), ('postcode', <django.forms.fields.CharField object at 0x7f4f5981e9d0>), ('tel', <django.forms.fields.CharField object at 0x7f4f5981ea90>), ('sex', <django.forms.fields.ChoiceField object at 0x7f4f5981eb50>), ('photo', <django.forms.fields.ImageField object at 0x7f4f5981ebd0>)])¶
-
media
¶
-
-
class
eggplant.profiles.forms.
SignupForm
(data=None, files=None, auto_id=u'id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False)[source]¶ Bases:
eggplant.profiles.forms.ProfileForm
-
base_fields
= OrderedDict([('first_name', <django.forms.fields.CharField object at 0x7f4f5981e610>), ('middle_name', <django.forms.fields.CharField object at 0x7f4f5981e6d0>), ('last_name', <django.forms.fields.CharField object at 0x7f4f5981e790>), ('address', <django.forms.fields.CharField object at 0x7f4f5981e850>), ('city', <django.forms.fields.CharField object at 0x7f4f5981e910>), ('postcode', <django.forms.fields.CharField object at 0x7f4f5981e9d0>), ('tel', <django.forms.fields.CharField object at 0x7f4f5981ea90>), ('sex', <django.forms.fields.ChoiceField object at 0x7f4f5981eb50>), ('photo', <django.forms.fields.ImageField object at 0x7f4f5981ebd0>), ('email', <django.forms.fields.EmailField object at 0x7f4f5981ec50>), ('password1', <allauth.account.forms.SetPasswordField object at 0x7f4f5981ecd0>), ('password2', <allauth.account.forms.PasswordField object at 0x7f4f5981ed90>)])¶
-
clean_email
()[source]¶ Check if user is already registered and if so raise validation error.
It may be considered a security hole to inform if a user is registered or not but it improves usability.
-
declared_fields
= OrderedDict([('first_name', <django.forms.fields.CharField object at 0x7f4f5981e610>), ('middle_name', <django.forms.fields.CharField object at 0x7f4f5981e6d0>), ('last_name', <django.forms.fields.CharField object at 0x7f4f5981e790>), ('address', <django.forms.fields.CharField object at 0x7f4f5981e850>), ('city', <django.forms.fields.CharField object at 0x7f4f5981e910>), ('postcode', <django.forms.fields.CharField object at 0x7f4f5981e9d0>), ('tel', <django.forms.fields.CharField object at 0x7f4f5981ea90>), ('sex', <django.forms.fields.ChoiceField object at 0x7f4f5981eb50>), ('photo', <django.forms.fields.ImageField object at 0x7f4f5981ebd0>), ('email', <django.forms.fields.EmailField object at 0x7f4f5981ec50>), ('password1', <allauth.account.forms.SetPasswordField object at 0x7f4f5981ecd0>), ('password2', <allauth.account.forms.PasswordField object at 0x7f4f5981ed90>)])¶
-
media
¶
-
eggplant.profiles.middleware module¶
eggplant.profiles.models module¶
-
class
eggplant.profiles.models.
UserProfile
(id, user, middle_name, address, postcode, city, tel, tel2, sex, photo, created, changed)[source]¶ Bases:
django.db.models.base.Model
-
exception
DoesNotExist
¶ Bases:
django.core.exceptions.ObjectDoesNotExist
-
UserProfile.
FEMALE
= 'female'¶
-
UserProfile.
MALE
= 'male'¶
-
exception
UserProfile.
MultipleObjectsReturned
¶ Bases:
django.core.exceptions.MultipleObjectsReturned
-
UserProfile.
OTHER
= 'other'¶
-
UserProfile.
SEX_CHOICES
= (('', '-----'), ('female', 'female'), ('male', 'male'), ('other', 'other'))¶
-
UserProfile.
accounts
¶
-
UserProfile.
administrator_for
¶
-
UserProfile.
full_name
¶ Returns member’s full name.
-
UserProfile.
get_next_by_changed
(*moreargs, **morekwargs)¶
-
UserProfile.
get_next_by_created
(*moreargs, **morekwargs)¶
-
UserProfile.
get_previous_by_changed
(*moreargs, **morekwargs)¶
-
UserProfile.
get_previous_by_created
(*moreargs, **morekwargs)¶
-
UserProfile.
get_sex_display
(*moreargs, **morekwargs)¶
-
classmethod
UserProfile.
in_department
(department, only_active_accounts=True)[source]¶ Returns the user profiles linked to the given department via: UserProfile -> Account -> DepartmentMembership -> Department
-
UserProfile.
objects
= <django.db.models.manager.Manager object>¶
-
UserProfile.
permissions
¶
-
UserProfile.
photo
¶ Just like the FileDescriptor, but for ImageFields. The only difference is assigning the width/height to the width_field/height_field, if appropriate.
-
UserProfile.
user
¶
-
UserProfile.
userprofilepermission_set
¶
-
exception
eggplant.profiles.tests module¶
eggplant.profiles.urls module¶
eggplant.profiles.views module¶
-
class
eggplant.profiles.views.
NewUserPassword
(**kwargs)[source]¶ Bases:
eggplant.core.views.LoginRequiredMixin
,allauth.account.views.PasswordSetView
Set password only for a new user. Existing users can use password change.
-
form_class
¶ alias of
NewUserSetPasswordForm
-
success_url
= <django.utils.functional.__proxy__ object>¶
-
-
class
eggplant.profiles.views.
Profile
(**kwargs)[source]¶ Bases:
eggplant.core.views.LoginRequiredMixin
,django.views.generic.edit.FormView
Profile form view.
-
form_class
¶ alias of
ProfileForm
-
success_url
= <django.utils.functional.__proxy__ object>¶
-
template_name
= 'eggplant/profiles/profile_detail.html'¶
-
Module contents¶
eggplant.roles package¶
Subpackages¶
Submodules¶
eggplant.roles.admin module¶
eggplant.roles.models module¶
-
class
eggplant.roles.models.
RoleAssignment
(id, role, user)[source]¶ Bases:
django.db.models.base.Model
-
ACCOUNTANT
= 'accountant'¶
-
CASHIER
= 'cashier'¶
-
COMMUNICATOR
= 'communicator'¶
-
exception
DoesNotExist
¶ Bases:
django.core.exceptions.ObjectDoesNotExist
-
exception
RoleAssignment.
MultipleObjectsReturned
¶ Bases:
django.core.exceptions.MultipleObjectsReturned
-
RoleAssignment.
PACKER
= 'packer'¶
-
RoleAssignment.
PURCHASER
= 'purchaser'¶
-
RoleAssignment.
ROLE_CHOICES
= (('purchaser', <django.utils.functional.__proxy__ object at 0x7f4f5aa63c10>), ('communicator', <django.utils.functional.__proxy__ object at 0x7f4f5aa63c50>), ('packer', <django.utils.functional.__proxy__ object at 0x7f4f5aa63c90>), ('cashier', <django.utils.functional.__proxy__ object at 0x7f4f5aa63cd0>), ('accountant', <django.utils.functional.__proxy__ object at 0x7f4f5aa63d10>))¶
-
RoleAssignment.
get_role_display
(*moreargs, **morekwargs)¶
-
RoleAssignment.
objects
= <django.db.models.manager.Manager object>¶
-
RoleAssignment.
user
¶
-
eggplant.roles.urls module¶
eggplant.roles.views module¶
Module contents¶
Submodules¶
eggplant.factories module¶
eggplant.urls module¶
Module contents¶
Eggplant is an open source food coop platform.
It allows buying and selling food products directly between farmers and consumers, cutting out the middle man, transportation, packaging etc.
Eggplant is good for the environment and good for you.
Eggplant¶
Eggplant is an open source web application that provides simple and flexible infrastructure for organizing food coops and other local community-driven projects.
How to contribute¶
Read our documentation to get started reporting bugs, developing code etc. The project description, organisation and goals are on our website eggplant.dk. The list of tickets is available on our GitHub project.
Write code, write tests, have fun.
Get in touch¶
For AFK stuff, you can join us in Copenhagen on meetup.com.
We use Slack for ad-hoc communication: Click to recieve an invitation. The techical discussion takes place on Slack#teamblue. The design and organisational issues can also be raised on Slack#teamgreen.