Django Wagtail forms based on models - django

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.

Related

Create custom page view counter in Django

I want to create my own view counter. I got inspired from django-hitcount. I read all models of this app.
In these lines:
class HitCountMixin(object):
"""
HitCountMixin provides an easy way to add a `hit_count` property to your
model that will return the related HitCount object.
"""
#property
def hit_count(self):
ctype = ContentType.objects.get_for_model(self.__class__)
hit_count, created = HitCount.objects.get_or_create(
content_type=ctype, object_pk=self.pk)
return hit_count
I couldn't understand the meaning and usage of ContentType and get_for_model(self.__class__). Can anyone help me?
Source of this mixin is here.
Since HitCountMixin can be inherited by different models in your app, HitCount model must be in some way connected to these models with a relation.
Here you can think of ContentType as a way of creating dynamic relation unlike it is with e.g. ForeignKey where you are bound to use the relation only with one model (table).
get_for_model is just Django's helper method for getting ContentType instance for given model because each model (table) would have its corresponding ContentType instance.
With example model using this mixin:
class Example(models.Model, HitCountMixin):
pass
ContentType.objects.get_for_model(self.__class__) would return ContentType instace for model Example
You can read more about ContentTypes in Django documentation

create model formsets from same model but with different model forms

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.

Django non-rel - How to create forms with EmbeddedModelField in the model?

I have setup for Django non-rel with Mongodb as backend. In models, I used EmbeddedModelField for quite a few times as I love those concepts of Non relational DBs. But, when it comes to rendering forms. I got stuck,
I created Form as normal form of Django but django showing Type error {model} in the title bar.
Has anybody know how can I create form fields for EmbeddedModelField in Django non-rel?
Just implement a formfield class by yourself.
implement formfield in forms.py
specify which form you want to use with this model in models.py
implementing a formfield is a piece of cake, you just need to implement these two methods in the class:
to_python(self, value)
prepare_value(self, value)
If you implement it with inheritance of old formfield class, you could use the widget attached on that formfield. (widget means the UI will be rendered on the webpage by template system)
Reference for implementing formfield: How to use ListFields in Django's admin
And you could implement your own widget by overriding the original widget of a formfield.
For instance, take a look at django documentations: Django docs - widgets

whats the difference between Django models and forms?

I am new to Django and can't understand the models and forms. Can any one suggest me the differences and tutorials related to them.
Basically, a model encapsulates information about something (i.e., it models it), and is stored in the database. For example, we could model a person:
from django import models
class Person(models.Model):
name = models.CharField(max_length=100)
age = models.PositiveIntegerField()
height = models.FloatField()
weight = models.FloatField()
Whenever a model instance is created and saved, Django stores it in the database for you to retrieve and use at a later date.
On the other hand, forms correspond to HTML forms, i.e., a set of fields which are presented to the end user to fill some data in. A form can be completely independent of a model, for example a search form:
from django import forms
class SearchForm(forms.Form):
search_terms = forms.CharField(max_length=100)
max_results = forms.IntegerField()
When submitted, Django takes care of validating the values the user entered and converting them to Python types (such as integers). All you then have to do is write the code which does something with these values.
Of course, if you have created a model, you will often want to allow a user to create these models through a form. Instead of having to duplicate all the field names and create the form yourself, Django provides a shortcut for this, the ModelForm:
from django.forms import ModelForm
class PersonForm(forms.ModelForm)
class Meta:
model = Person
As for further reading, I would start with the Django documentation, which includes a tutorial on creating and using models, and a fairly in-depth look at forms. There are also plenty of Django books and online tutorials to help you along.
Models are related to the database abstraction layer covered in Tutorial 1:
http://docs.djangoproject.com/en/dev/intro/tutorial01/
It covers everything from what they are, what the philosophy is, what it's abstracting (raw sql). Read it and come back if you have any questions, because it's really good.
Tutorial 4 covers forms.
http://docs.djangoproject.com/en/dev/intro/tutorial04/
The forms framework is just a helper for HTML forms. There are also ModelForms, based on the forms framework, that ties models together with forms, but the core of it is a framework for dealing with HTML form display, validation, and processing.

Admin Form Integration for Custom Model Fields in Django

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