Django: One model multi-steps forms - django

I am trying to build a multi-step forms from one Django model which have 9 fields. The forms are validated in each step and saved after final step into database.
The quick solution I can think of beside Django formWizard is
I have a django model like this:
class Question(models.Model):
name = models.CharField(max_length=100)
Description = models.TextField()
filter = models.CharField(max_length=20)
I split the form into three
class Filter(forms.ModelForm):
class Meta:
model = Question
exclude = ('filter',)
class Name(forms.ModelForm):
class Meta:
model = Question
fields = ('name',)
class Descripton(forms.ModelForm):
class Meta:
model = Question
fields = ('description',)
Write urls and integrate with views for different steps. The question is how can I validate and save multi-steps forms data at last step?

What is your use case for splitting this up into three steps rather than in a single one?
That aside, a simple solution would be to:
Clean/validate the partial data after each submit.
Send the partial data back in hidden fields to your template for the subsequent steps (perhaps Name can inherit or be initialized using Filter, same with Description taking in Name).
Then on the final submit, you'll have all the previous data (some in hidden fields) so you can save it all to your database.

Related

Django REST ModelSerializer --- General Question

I am working through a tutorial that includes the building of an articles app. I have an Article model that I am serializing and I am curious about why I need to explicitly set certain fields when using a ModelSerializer.
Here is my model:
from django.db import models
from core.models import TimestampedModel
class Article(TimestampedModel):
slug = models.SlugField(db_index=True, max_length=255, unique=True)
title = models.CharField(db_index=True, max_length=255)
description = models.TextField()
body = models.TextField()
author = models.ForeignKey('profiles.Profile', on_delete=models.CASCADE, related_name='articles')
def __str__(self):
return self.title
Pretty standard stuff. Next step is to serialize the model data in my serializers.py file:
class ArticleSerializer(serializers.ModelSerializer):
author = ProfileSerializer(read_only=True) # Three fields from the Profile app
description = serializers.CharField(required=False)
slug = serializers.SlugField(required=False)
class Meta:
model = Article
fields = (
'author',
'body',
'createdAt',
'description',
'slug',
'title',
'updatedAt',
)
Specifically, why do I need to explicitly state the author, description, and slug fields if I am using serializers.ModelSerializer and pulling those fields in from my model in my class Meta: below?
Thanks!
In the Django-Rest-Framework documentation, drf-docs/model_serializer/specifying-which-fields-to-include it says:
If you only want a subset of the default fields to be used in a model serializer, you can do so using fields or exclude options, just as you would with a ModelForm. It is strongly recommended that you explicitly set all fields that should be serialized using the fields attribute. This will make it less likely to result in unintentionally exposing data when your models change.
Therefore by using fields = in the Serializer META, you can specify just the needed fields, and not returning vital fields like id, or exessive information like updated and created timestamps.
You can also instead of using fields, use exclude, which again takes in a tuple, but just excludes the fields you don't want.
These are especially useful when your database table contains a lot of information, returning all this information, especially if it is listed, can result in large return JSON's, where the frontend may only use a small percentage of the sent data.
DRF has designed their framework like this to specifically combat these problems.
In my opinion, we should define field in serializer for:
Your api use serializer don't need all data of your models. Then you can limit field can get by serializer. It faster if you have so much data.
You dont want public all field of your model. Example like id
Custom field in serializer like serializers.SerializerMethodField() must define in fields for work
Finally, iF you dont want, you can define serializer without define fields. Its will work normally

How do Meta field names correspond to model attributes

I am writing a Django Model and different Forms to modify the model's data.
For simplification let's say my model is as follows:
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
birth_date = models.DateField()
# (...) some other properties
__identity_card_front = models.FileField(blank=True)
class IdentityCardForm(forms.ModelForm):
class Meta:
model = Profile
fields = ('__identity_card_front',)
My question is: must the fields names correspond to the attributes of Profile class (the exact name of the variables definition)? Do these strings determine the HTML form field name that will be searched in form validation? And if so, how can I customise it? I don't want to have to obligatorily call my field name '__identity_card_front', but instead maybe something like 'id_front', 'idf', etc.
I have seen labels might be used, but I was not clear how Django treats fields tags. I could not find either a good explanation on the Docs without getting lost around low-level class definitions and properties.
Note: I am using django-2.0

Create forms from model, save to another

I'm building a survey-type app, where the questions are entered/stored in a model (by an admin). I want to use this model to auto-create a user facging form (the response will be stored in another model.
class Question(models.Model):
question_text = models.CharField(max_length=150)
questionnaire = models.ForeignKey(Questionnaire) # 'lump' questions together
class Response(models.Model):
question = models.ForeignKey(Question)
response_text = models.CharField(max_length=150)
user = models.IntegerField() # used to record user ID
I'm not sure what's the correct approach - using a ModelForm (populating through init) or a 'regular' form - where I'm not sure how I output my results - using print or adding to a form property.
Thanks.
In your init you can
self.fields['your_field']=forms.ModelChoiceField(queryset=YourQuerySet.objects.get(pk=X)) // alternatively a filter with first()
to enforce the initial foreign key object

Django forms with odd model relationship

I am working with an existing database that I can not modify and having some trouble trying to deal with presenting forms for modifying the database in Django. The structure in question is as follows and all models are unmanaged.
class Persons(models.Model):
personid = models.BigIntegerField(primary_key=True, db_column='PersonID')
....
class Phones(models.Model):
phoneid = models.BigIntegerField(primary_key=True, db_column='PhoneID')
number = models.CharField(max_length=60, db_column='Number', blank=True)
type = models.CharField(max_length=15, db_column='Type', blank=True)
...
class Personsphones(models.Model):
personphoneid = models.BigIntegerField(primary_key=True, db_column='PersonPhoneID')
personid = models.ForeignKey(Persons, db_column='PersonID')
phoneid = models.ForeignKey(Phones, db_column='PhoneID')
...
I want to create a form to display all of the 'Phones' associated with a particular 'Persons' and in addition be able to modify/add/remove 'Phones' belonging to a 'Persons'. Right now the only thing I can think of is to display the 'Phones' in a modelformset and then if one is added or removed manually set the 'Personsphones' relation. Any ideas on how to best deal with this model setup?
For making changes to your models you may want to use django-south http://south.aeracode.org/docs/
As far as displaying your 'Phone' under your forms.py you may want to set up class meta like so. With this any changes made to models will reflect on change
class Meta:
model = Persons
exclude = ('user')
In models you may want to use Foreignkey fore relationships between phones and Persons. Better seen in action here https://docs.djangoproject.com/en/dev/ref/models/fields/#foreignkey

Django Forms With foreign key

I have 2 models in django, and im also using ModelForm, my question is the second model have a froreignkey of the 1, and i want to have one page when generating the form. It's possible, how to link the two forms in one page.
Class Event(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField()
class Date(models.Model):
id = models.AutoField(primary_key=True)
start = models.DateTimeField()
end = models.DateTimeField()
event = models.ForeignKey("Event")
I also have
class EventForm(ModelForm)
Class Date(ModelForm)
What i want is to create the event in one page in my templates.
Thanks.
If you want to have this on the Django Admin, then you need to use inline models.
If you plan to create your own form (using ModelForms), then you need to use inline formets.