I need a model field composed of a numeric string for a Django app I'm working on and since one doesn't exist I need to roll my own. Now I understand how "get_db_prep_value" and such work, and how to extend the Model itself (the django documentation on custom model fields is an invaluable resource.), but for the life of me I can't seem to figure out how to make the admin interface error properly based on input constraints.
How do I make the associated form field in the admin error on incorrect input?
Have a look at the Form and field validation section in the Django documentation, maybe that's what you're looking for?
You would have to make a new type of form field for your custom model field.
All you need to do is define a custom modelform which uses your new field, and then tell the admin to use that form to edit your models.
class MyModelForm(forms.ModelForm):
myfield = MyCustomField()
class Meta:
model = MyModel
class MyModelAdmin(admin.ModelAdmin):
form = MyModelForm
Related
I have a simple model that references my Auth_User_model. I want to create a simple form that creates an OAuth2Client which inherits from functionality from OAuth2ClientMixin.
class OAuth2Client(models.Model, OAuth2ClientMixin):
user_id = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
class FormPage(AbstractForm):
class Meta:
model = OAuth2Client
What I am unclear about is how to bind my Form Page to my model? I'm using this high level tutorial but seems a bit geared to the AbstractEmailForm. Which doesn't work for me. How do I create a form based on a model?
The wagtail.contrib.forms app is geared towards simple data collection such as surveys, where the form fields are defined editorially through the admin interface - this isn't the case here, where the form fields are inherently tied to the model definition set up in code. A Django ModelForm is a better fit:
from django.forms import ModelForm
class OAuth2ClientForm(ModelForm):
class Meta:
model = OAuth2Client
If you want to incorporate this form into a Wagtail page rather than a plain Django view, you can override the serve method on the page model, which has very similar behaviour to a Django view function (taking a request object as an argument, and returning a response object) - this is where you would put the logic for checking request.POST and processing or rendering the form accordingly.
I have an area where teachers can put homeworks for students.
Students can see these homeworks and when they click "send homework" button. they can fill a form so Teachers can see the homeworks from admin panel.
I have class to post homework.
I have 4 fields in class to post homework.
Fields = ["student number","Deadline","Lecture","Files"]
when students posting their homeworks, I want only use 2 ["student number","files"] fields for the form and I want other fields ["deadline","Lecture"] to be filled automatically from database.
What is the best way do it?
Quoting django model clean method docs:
Model.clean() This method should be used to provide custom model validation, and to modify attributes on your model if desired. For instance, you could use it to automatically provide a value for a field, or to do validation that requires access to more than a single field.
For your scenario:
import datetime
from django.db import models
class Homeworks(models.Model):
...
def clean(self):
self.Deadline = datetime.date.today() + some delta time
self.Lecture = ...
Also, remove this 'self-filled' fields from admin form interface:
class HomeworksAdmin(admin.ModelAdmin):
fields = ["student number","Files"]
I have an Image model in my Django project. Because of different types of Image I have created three ModelForms according to each type:
class Xray(ModelForm):
#extra_field: Choice Field with specific options for Xray
class Meta:
model = Image
class Internal(ModelForm):
#extra_field: Choice Field with specific options for Internal
class Meta:
model = Image
class External(ModelForm):
#extra_field: Choice Field with specific options for External
class Meta:
model = Image
Each ModelForm has a save logic implemented. I want to create a model formset one for each Image type but want to use the correct ModelForm for each type of Image. I won't use this formset for editing thus I always want it to be empty and have 5 forms(5 items). I can't seem to find in django docs where i can use a specific form for a formset. Only a specific formset (inherit from BaseModelFormSet)
Is it possible to use specific form for each model_formset?
You can do the following:
from django.forms.models import modelformset_factory
from someproject.someapp.models import Image
from someproject.someapp.forms import Internal
ImageFormSet = modelformset_factory(Image, form=Internal)
Here are the docs for modelform_factory, which don't mention the form argument. However, in the "Note" below the examples therein that the function delegates to formset_factory, which is documented to take the form argument. It's just a minor docs issue, and might be a good reason to create a fork of Django, make an update to the docs, and create a pull request.
Is there a simple way to replace a form field in Django with another form? Specifically, I have a one-to-one relationship between two models, and it would be great if I could define a field to actually be defined as another form, something like this:
class FirstModelForm(forms.ModelForm):
class Meta:
model = FirstModel
class SecondModelForm(forms.ModelForm):
second = forms.InnerForm(form=FirstModelForm)
class Meta:
model = SecondModel
Any ideas? Or should I write it myself and submit to Django codebase? ;-)
Can I get a form into Django Administrator page, that I have defined in forms.py?
Can I also get this form into Model inlines of Django Administrator page ?
To be clear, this is what I call inline:
class AnswerInline(admin.StackedInline):
...
Yeah, it's a bit complicated but the docs are actually clear here:
InlineModelAdmin.form
The value for form defaults to ModelForm. This is what is passed through to
inlineformset_factory when creating the formset for this inline.
So create your form class and then refer to it in the inline, like so:
class MyForm(forms.ModelForm):
…
class AnswerInLine(admin.StackedInline):
form = MyForm