Skip to content

MagiModel utils

deby edited this page Feb 14, 2023 · 19 revisions

↑ Parent: Utils

Within the model itself

Class methods

All your models that inherit from MagiModel or BaseMagiModel provide the following class methods:

Name Description Parameters Return value
selector_to_owner Django model query selector you can use to retrieve the User object that correspond to the owner of this instance. None String query selector (example: 'owner', 'account__owner', 'chapter__book__owner')
owner_ids Get the list of ids of the fk_as_owner. For example, for a card that uses accounts as owner, it would return the list of account ids owned by the user. For the 'chapter__book__owner' case, it would return the list of chapters owned by the user. user List of ids
owner_collection For example for account would return AccountCollection. None An instance of a MagiCollection or None
owners_queryset Get the queryset that could get you the fk_as_owner (see owner_ids) user queryset

Methods

All your models that inherit from MagiModel or BaseMagiModel provide the following methods:

Name Description Parameters Return value
is_owner Is the user in parameters the owner of this instance? user True or False

Optional methods

In all your models that inherit from MagiModel or BaseMagiModel, you may provide the following optional methods:

Key Value Example
get_item_url Set your own URL. Can be used to add parameters to an existing URL, for example, or to link to an external website. Will not work if item view is disabled. Use display_item_url for that. property(lambda _s: u'/other_url?id={}'.format(_s.id))
get_ajax_item_url Same as get_item_url but for Ajax URL (opened in modal for example)

Tools

All your models that inherit from MagiModel or BaseMagiModel provide the following properties or methods (not meant to be overriden):

Key Value Example
get_owner_from_pk Class method that takes the owner's pk and performs a database query to retrieve the actual owner instance ⚠️
owner_collection Class method that return the owner's collection
is_owner Method that takes a user and returns wether or not that user is the owner of the item
owner_unicode Unicode representation of the owner
real_owner Owner can be cached, this is a way to retrieve the actual owner instance. It performs a query ⚠️
has_item_view_permissions Method that takes context (with request in it) and checks wether or not the current user is allowed to open the item view (since BaseMagiModel don't have linked collections, it will returnFalse)

All your models that inherit from MagiModel (not BaseMagiModel) provide the following properties or methods (not meant to be overriden):

Key Value Example
collection Associated MagiCollection object (retrieved using the collection_name) Instance of IdolCollection
collection_title MagiCollection setting for localized title _('Idol')
collection_plural_name MagiCollection setting for non-localized plural For 'idol', it would be idols, for 'activity', it would be activities
collection_plural_title MagiCollection setting for localized plural _('Idols')
item_url The URL to the ItemView /idol/1/Nozomi/
ajax_item_url The URL to the ajax ItemView /ajax/idol/1/
full_item_url The URL to the ItemView with the domain //sample.com/idol/1/Nozomi/
http_item_url The URL to the ItemView with the domain and http (when // URLs are not supported, such as in emails or when sharing) http://sample.com/idol/1/Nozomi/
edit_url The URL of the EditView /idols/edit/1/
ajax_edit_url The URL of the ajax EditView /ajax/idols/edit/1/
report_url The URL to report this item /idols/report/1/
open_sentence Localized sentence to open this item (open the ItemView) Open idol
edit_sentence Localized sentence to edit this item, also used to open the page to edit this item (EditView) Edit idol
delete_sentence Localized sentence to delete this item Delete idol
report_sentence Localized sentence to report this item, or open the page to report this item Report idol
d_unicodes Dict of languages and their own version of the unicode representation of the item. Can be heavy to load as it changes the user's language to retrieve them {'ja': u'穂乃果'}

These properties are only available for MagiModel and not BaseMagiModel.

By defaults, unicode for MagiModel (not BaseMagiModel) will try to return t_name, then the value of collection_title, then the value of collection_name.

Optional properties

In all your models that inherit from MagiModel or BaseMagiModel, you may provide the following optional properties:

Key Value Example
fk_as_owner See MagiModel, section "Have an owner"
thumbnail_size See Optimize or resize images and MagiModel images and files
tinypng_settings See Optimize or resize images and MagiModel images and files
icon_for_prefetched See MagiFields section "Reverse relations and many to many" and Customize views with MagiModel properties
image_for_prefetched See MagiFields section "Reverse relations and many to many" and Customize views with MagiModel properties
template_for_prefetched See MagiFields section "Reverse relations and many to many" and Customize views with MagiModel properties include/mini_card.html
image_for_favorite_character If this model is used for favorite characters (see Characters), this can be used to specify which image to use property(lambda _s: _s.icon_image_url)
display_item_url See Customize views with MagiModel properties
display_ajax_item_url See Customize views with MagiModel properties
selector_to_collected_item Example: Card has OwnedCard set as collectible. In OwnedCard, there's a foreign key to a card. This setting (in OwnedCardCollection) is the name of the foreign key. Defaults to model_name in card collection. See Collectible. 'main_card'
birthday_banner See Characters
birthday_banner_hide_title See Characters
birthday_banner_css_class See Characters
IS_PERSON Defaults to False

Utils functions

from magi.utils import modelHasField
Name Description Parameters Return value
dumpModel Take an instance of a model and transform it into a dictonary with all its info (easily flattenable). Allows to delete an instance without losing data (used by Report collection) instance dictionary
modelHasField Does this model class contain the field field_name in database? model, field_name bool
modelGetField Fail-safe way to get a field from a model by its name model, field_name field or None
modelFieldVerbose Get the verbose name specified in the model for that field. Ex: _('Idol') model, field_name Translated string
modelFieldHelpText Get the help text specified in the model for that field. model, field_name Translated string

Owner

All models must have an owner:

${PROJECT}/models.py:

class Idol(MagiModel):
    owner = models.ForeignKey(User, related_name='idols')

Because it's very common to associate an item to an account and not directly to an owner, since account already has an owner, you may make your model class inherit from AccountAsOwnerModel instead of MagiModel:

from magi.models import AccountAsOwnerModel

class OwnedCard(AccountAsOwnerModel):
    """
    Will automatically provide a cache for the account and provide `owner` and `owner_id` properties.
    """
    account = models.ForeignKey(Account, related_name='ownedcards')

If your model doesn't have a direct owner or account, you may fake it by providing properties for owner and owner_id, and specify fk_as_owner in your model:

class Book(MagiModel):
    owner = models.ForeignKey(User, related_name='books')

class Chapter(MagiModel):
    book = models.ForeignKey(Book, related_name='chapters')
    fk_as_owner = 'book'

    @property
    def owner(self):
        return self.book.owner

    @property
    def owner_id(self):
        return self.book.owner_id

If you have multiple layers of foreign keys before finding the owner, you may specify selector_to_owner:

class Paragraph(MagiModel):
    chapter = models.ForeignKey(Chapter, related_name='paragraphs')
    fk_as_owner = 'chapter'
    selector_to_owner = classmethod(justReturn('chapter__book__owner'))
    ...

Note: Account model MUST contain an actual model field owner.

In our example above, book would be retrieved when the property owner is accessed, resulting in extra database queries. To optimize this, you can:

  • Set your MagiCollection queryset to use select_related to get the book:
    class ChapterCollection:
        queryset = models.Chapter.objects.select_related('book')
  • Use the provided CacheOwner - Or save a cache of the book in your model (recommended)

If fk_as_owner is provided, a property real_owner is available to force the access to the actual User object. It should be used scarcely because it will perform a SQL query every time it's accessed.

↓ Content

→ Next: Python utils

I. Introduction

II. Tutorials

  1. Collections
    1. MagiModel
    2. MagiCollection
    3. MagiForm
    4. MagiFiltersForm
    5. MagiFields
  2. Single pages
  3. Configuring the navbar

III. References

IV. Utils

V. Advanced tutorials

VI. More

Clone this wiki locally