Passing Django form data to frondend framework (DRF) - django

Background
I ran into a really annoying problem here. I've decided to use Svlete as my frontend. Also, I have a lot of endpoints in my REST api that expect form data. In the past I would just forms.py in my app's directory and then add a form like:
class ProductsModelForm(forms.ModelForm):
class Meta:
model = Product
fields = (
'name',
'weight',
)
class ProductForm(forms.Form):
name = forms.CharField()
weight = forms.IntegerField()
And would then use
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Submit</button>
</form>
In the HTML template. All cool.
DRF + Frontend Framework
Obviously I still have the form in the forms.py but now I have to define the form in the fronend too. And with bigger forms it gets really annoying because I always have to compare that I have every field in my frontend form that I have defined in the django backend form. Is ther any solution to this?

Use DRF SERIALIZERS.
DRF SERIALIZERS ARE JUST LIKE FORMS; THEY VALIDATE AND CLEAN DATA.
Forms are best for monolithic sites.

Related

Django OneToOneField show up on ModelForm of other entity?

I have the following classes:
class Account(models.Model):
instance = models.OneToOneField(Instance, blank=True, null=True)
class Instance(models.Model):
is_ready = models.BooleanField(default=False, verbose_name=_('Ready?'))
Right now the relationship between Account and Instance is set by a ModelForm for Account via Account.instance.
I would like to be able to set Account.instance via a ModelForm on Instance. Is that possible?
A ModelForm is:
a helper class that lets you create a Form class from a Django model.
An idea would be to write a custom model Field to address this issue. However, according to the relevant chapter of Writing Custom Model Fields
Fields in a model must somehow be converted to fit into an existing database column type.
Trying to spot the available postgreSQL column types I found this page which does not seem to provide a solution.
On the other hand, there is an old but updated SO post, which gives a solution that actually renders both forms in an HTML page and -this way- you gather all the needed fields in one form.
forms.py
class AccountForm(forms.ModelForm):
... Do stuff if necessary ...
class Meta:
model = Account
fields = ('the_fields', 'you_want')
class InstanceForm (forms.ModelForm):
... Do other stuff if necessary ...
class Meta:
model = Instance
fields = ('the_fields', 'you_want')
views.py
...
def register(request):
if request.method == 'POST':
account_form = AccountForm(request.POST)
instance_form = InstanceForm(request.POST)
if account_form.is_valid() and instance_form.is_valid():
account_form.save()
instance_form.save()
...
the_template.html
<form action="." method="post">
{% csrf_token %}
{{ account_form.as_p }}
{{ instance_form.as_p }}
<input type="submit" value="Submit">
</form>
This is also the idea of the admin's class InlineModelAdmin.
In the admin, for example, Account will become an inline model to Instance (which is a bad name for a django class).
admin.py:
from django.contrib import admin
class InstanceInline(admin.TabularInline):
model = Instance
class AccountAdmin(admin.ModelAdmin):
inlines = [
InstanceInline,
]

How to store social usernames/links in Django?

I have a personal blog written with Django. I want to make my social links/usernames dynamic so I can change them whenever I want.
I'm doing this with charfields. I'm adding new charfield for each social username/link field then my template's getting these usernames to show them in a tags. It's okay but I think it's not the easiest way.
Am I wrong or there is a better way to do this?
Maybe it would be easier to create a model for it. That way you would be able to add/remove social links without having to touch the code.
from django.conf import settings
from django.db import models
class SocialProfile(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='social_profiles')
network = models.CharField(max_length=100)
username = models.CharField(max_length=100)
url = models.URLField(max_length=500)
Then if you are using Django Admin, you could add this model as a TabularInline of the User model for example.
In your templates you could render the links dynamically:
{% for profile in request.user.social_profiles.all %}
{{ profile.username }}
{% endfor %}
Something like that.

How to replace form field with custom layout in Django?

I have a model form field which is a choice field. Instead of having the default widget:
I would like to have a grid of cards like so:
With each of the choices that would have been in the default widget in a card.
How do I edit the python form to achieve this?
Here is my form:
from django import forms
from . import models
class PostJobForm(forms.ModelForm):
class Meta:
model = models.Job
fields = [
'title',
'description',
'pay',
'category'
]
You will have to move away from default django forms and create the forms using html, css and js the way you want.
When using django forms, it uses default templates.
<form method="post" action"">
<input type="text" id="id_title" name="title">
<!--this input is for title field of your model form-->
</form>
as shown above you can do it for any field that you want
IMP keep the name attribute of input and that of model field same

Internationalizing a Django class-based generic view (CreateView)?

I am using Django 1.9 class-based generic views, for example CreateView. When I visit the "create" page, some parts are translated (into French in my example), so I know my config and wiring is correct, but the form fields (auto-named by the view) are not (i.e. form.as_p).
How can I get form fields to be used from my translations file? (For example, "Name" is a field, already translated, but not picked up by the form.as_p).
One answer is to list out the fields individually in the template with {% trans %} tags. I was hoping to avoid that.
My example is similar to the one in the docs, so let me repeat that example here. First, code:
from django.views.generic.edit import CreateView
from myapp.models import Author
class AuthorCreate(CreateView):
model = Author
fields = ['name']
Then display template:
<form action="" method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Save" />
</form>
Have a look at the Lazy Translation:
This is essential when calls to these functions are located in code paths that are executed at module load time.
This is something that can easily happen when defining models, forms and model forms, because Django implements these such that their fields are actually class-level attributes.
So, if you have a form, you can use ugettext_lazy to translate:
from django.db import models
from django.utils.translation import ugettext_lazy as _
class MyThing(models.Model):
name = models.CharField(help_text=_('This is the help text'))
You can mark names of ForeignKey, ManyToManyField or OneToOneField relationship as translatable by using their verbose_name options:
class MyThing(models.Model):
kind = models.ForeignKey(
ThingKind,
on_delete=models.CASCADE,
related_name='kinds',
verbose_name=_('kind'),
)

How do I handle multiple forms in Django with many-to-many relationship

In my view I have a the Booking information, in the booking I have a many-to-many relationship to the size of the group in the booking and the age. The class (group size, age) has the many-to-many relationship. When the booking is made I would like the user to be able to add class details. So a booking can have many classes.
I have tried using inline_formset_factory but it did not like the many-to-many relationship and according to the docs inline_formset_factory is for a ForeignKey relationship (I could easily be wrong here). Also it seems I need a booking instance before I can use the inline_formset_factory (Though again I could be wrong)
So to recap I'm new to django and I'm trying to add many classes to a booking via a form which is with the booking form. I'm just not sure if I'm on the right track.
I hope this made sense. Thanks in advance.
Rather than creating the form yourself, instead use a ModelForm which will tie your form to a model in your app, automatically creating the field types it needs to save or edit an instance of the model it is linked with.
The simplest way to add a Booking instance to you database would be to use a ModelForm:
from django.db import models
from django.forms import ModelForm
class Booking(models.Model):
...
class BookingForm(ModelForm):
class Meta:
model = Booking
See the Django docs for more information on ModelForms. Next in your view create an instance of the BookingForm passing it in your template context:
def your_view(request):
if request.method == 'POST':
form = BookingForm(request.POST)
if form.is_valid():
booking = form.save()
return HttpResponseRedirect('/success/url/')
else:
form = BookingForm()
return direct_to_template(request, 'your/template.html', {
'form': form
})
For more information on dealing with forms in your views see using a form in a view in the Django docs. Next in your template you can simply print the entire form (and all the relevant fields) like so:
<form action="" method="post">
{{ form.as_p }}
<input type="submit" name="submit" value="submit">
</form>
See displaying a form using a template for more information on forms in templates.