I have a model, which has some fields stored in db. On top of it, I need to implement non-db fields, which would be loaded and saved using a custom API.
Users should interact with the model using the admin interface, Grappelli is used to enhance the standard Django admin.
I am interested in one of the following:
Model virtual fields or properties, where I can override how to read and save custom fields. (Simple python properties won't work with Django admin)
Editable callables for admin (not sure if it is even possible)
Any other means to display and process custom fields in admin, except of creating custom forms and moving the logic into the forms.
I think you can use a none-model class, which wrapper the Model class and have some extra fields, where you can set/get or save to other place
Related
I need to customise a through model of a many-to-many relationship, the customisation is subtle, because the user won't need do act manually, I try to explain myself better by explaining my use case with the following pseudo code:
RouterConfiguration
- vpn (many-to-many through VpnClient)
# other fields
VpnClient
- router: ForeignKey to RouterConfiguration
- vpn: ForeignKey to Vpn
- cert: ForeignKey to Cert
Vpn
# other fields
Cert
# (stores x509 certificates)
# other fields
The through model VpnClient has only one additional field, a ForeignKey to Cert, but I want VpnClient to automatically create a Cert instance without user interaction and until here there is no problem.
The problem comes in the Django Admin, because as far as I understood, it is not possible to use the classic many2many widget when using a through model:
When you specify an intermediary model using the through argument to a
ManyToManyField, the admin will not display a widget by default. This
is because each instance of that intermediary model requires more
information than could be displayed in a single widget, and the layout
required for multiple widgets will vary depending on the intermediate
model.
Reference: https://docs.djangoproject.com/en/1.10/ref/contrib/admin/#working-with-many-to-many-intermediary-models
But I don't want the user to insert any extra information. I just want to be able to control the model so it can perform a series of actions automatically.
So my question is: is it possible to have the classic admin widget with a custom through model? If there's no easy solution maybe I could try with a custom widget? Or maybe there is an alternative way to accomplish what I need?
PS: apparently there's a ticket for this use case: https://code.djangoproject.com/ticket/12203
I am developing a django application using Pinax Stripe(https://github.com/pinax/pinax-stripe). Pinax stripe is a bundled application which has a model called 'Plans'. Now in my application, I want to add some extra fields to the model 'Plans' in my application BUT without modifying the original pinax stripe application.
Something like this:
#models.py
from pinax-stripe.models import Plan
class UserProfile(models.Model):
#write the extra fields here
Is there any way I can do it and then register it with admin so i can add data to those fields in admin panel?
You can inherit the Plan models and add your own attributes:
from pinax-stripe.models import Plan
class MyPlan(Plan):
# add your attributes
pass
This works like normal inheritance in python, plus your custom attributes are migrated when you run a migration because the original pinax Plan is a subclass of models.Model.
However, be careful to not use attribute names that already exist in the pinax Plan model, since your new model will automatically take all the attibutes from Plan and Django cannot write migrations for duplicate fields.
You can simply subclass Plan and add whatever fields / methods you want:
from pinax-stripe.models import Plan
class UserProfile(Plan):
#write the extra fields here
I'd recommend you, use the OneToOne relationship like Django docs recommend to use in the User model
from pinax-stripe.models import Plan
class UserProfile(models.Model):
plan = models.OneToOneField(Plan , on_delete=models.CASCADE)
#write the extra fields here
You can download pinax folder from https://github.com/pinax/pinax-stripe into your app and edit models.py and admin.py files as per your requirement.
I've been searching a way to reproduce admin-actions behavior on my own tables using django-tables2. I haven't found any module to introduce this functionality to a ListView to derive from it and looking at ModelAdmin I see there are many methods implied on this.
Of course, I can add a form around my table to get the checkboxes and a submit button pointing to a view that works with the ids but I'm looging to get a combo to choose among different actions as in django-admin but also to have that 'actions' meta option to list some methods as the possible actions to perform.
I found django-actions which is still very young but also it introduces it's own page for operations and I just need to integrate functionality on my own model so I can connect some input type=select with the model actions.
Any comment is appreciated :)
There is no built-in solution for it. You have to implement your actions in your views and the functionality to your templates.
Add, edit and delete operations are very easy to implement in your views.py. This depends on your models, but you can trigger database manipulations from within your templates and keep the logic in your views.py.
You can also easily add a form to your templates as it is described in the docs:
# forms.py
from django.forms import ModelForm
from myapp.models import Article
# Create the form class.
class ArticleForm(ModelForm):
class Meta:
model = Article
fields = ['pub_date', 'headline', 'content', 'reporter']
model := Choose your model which you want to modify / add
fields := Select some fields from your model, which you want to show up in your form
This defines a form corresponding to your model, which can be used in your templates to modify or add an entity to your database.
We have a django application that is, at its core, a series of webpages with Forms which our users fill out in order. (We'll call the particular series of pages with forms on them a "flow".)
We will be white-labeling this application for a Partner -- the Partner will want to add some fields and even add some webpages with their own new Forms. This may result in a new order in which the Forms are filled out. (A new "flow", in addition to changes to existing Forms/Models or new Forms/Models.)
What is the best way to extend our existing, simple Forms-and-Models structure to use different Forms and Models depending on the running instance of the app (e.g. an environment variable)? Some things we thought about:
implement something like get_user_model for every Model and Form use in the app, which would look at the current environment
implement a more generic key-value store so that we're not bound by the current implementation's field types (i.e., have the data field name be part of the data as well)
a data model which tracks this particular environment's "flow" and which models it needs to use
subclass existing Models and Forms for each new white-label implementation
Model Field injection may be what you are looking for, take a look of this article
The approach boils down to three concepts:
Dynamically adding fields to model classes Ensuring Django’s model
system respects the new fields
Getting the load ordering correct for the above to work
Mezzanine has done a beautiful job implementing this model field injection with dynamic extra models via EXTRA_MODEL_FIELDS
I'm currently working on a model that has been already built and i need to add some validation managment. (accessing to two fields and checking data, nothing too dramatic)
I was wondering about the exact difference between models and forms at a validation point of view and if i would be able to just make a clean method raising errors as in a formview in a model view ?
for extra knowledge, why are thoses two things separated ?
And finnaly, what would you do ? There are already some methods written for the model and i don't know yet if i would rewrite it to morph it into a form and simply add the clean() method + i don't exactly know how they work.
Oh, and everything is in the admin interface, havn't yet worked a lot on it since i started django not so long ago.
Thanks in advance,
You should use model (field) validation to make sure the returning datatype meets your database's requirements. Usually you won't need this because django's builtin fields do this for you, so unless you've built some custom field or know what you are doing you shouldn't change things.
Form validation is where you clean the user's input, you can add a clean method for every form field by adding a clean_FIELD(self) method, e.g.
class ContactForm(forms.Form):
# Everything as before.
...
def clean_recipients(self):
data = self.cleaned_data['recipients']
if "fred#example.com" not in data:
raise forms.ValidationError("You have forgotten about Fred!")
# Always return the cleaned data, whether you have changed it or
# not.
return data
Before a Form's main clean method is ran, it checks for a field level clean for each of its fields
Generally models represent business entities which may be stored in some persistent storage (usually relational DB). Forms are used to render HTML forms which may retreive data from users.
Django supports creating forms on the basis of models (using ModelForm class). Forms may be used to fetch data which should be saved in persistent storage, but that's not only the case - one may use forms just to get data to be searched in persistent storage or passed to external service, feed some application counters, test web browser engines, render some text on the basis of data entered by user (e.g. "Hello USERNAME"), login user etc.
Calling save() on model instance should guarantee that data will be saved in persistent storage if and only data is valid - that will provide consistent mechanism of validation of data before saving to persistent storage, regardless whether business entity is to be saved after user clicks "Save me" button on web page or in django interactive shell user will execute save() method of model instance.