how I can load a model to multipleChoiceField - django

please y have been trying to show the table in the form, but I have not been able to do.
please clone and create database and run the project on github.
is too much code to paste here.
github: https://github.com/mattisbmx/django-multipleChoiceField
Model:
from django.db import models
from multiselect.fields import ManyToManyField
class Choice(models.Model):
choice = models.CharField(max_length=15)
def __unicode__(self):
return self.choice
class SampleModel(models.Model):
name = models.CharField(max_length=15)
funciones = ManyToManyField(Choice)
passwd = models.TextField()
def __unicode__(self):
return unicode(self.pk)
View:
def index(request):
data = {'form': forms.SelectForm()}
return render_to_response("multiselect/index.html", data,
context_instance=RequestContext(request
Form:
class SelectForm(forms.Form):
data = (('1', 'One'), ('2', 'Two'), ('3', 'Three'), ('4', 'Four')) #<--I think here I load the data model
choices = MultipleChoiceField(choices=data)
Thanks

You can use ModelMultipleChoiceField
class SelectForm(forms.Form):
choices = forms.ModelMultipleChoiceField(queryset=Choice.objects.all()) #Replace the queryset with the queryset of your choice.
If you wish to change the default widget
You can use widget=CheckboxSelectMultiple() or whichever you wish.

Related

django select related not giving expected result

I am querying select related between two models Requirements and Badge Requirement has a related badge indicated by badge_id Models are,
class Badge(models.Model):
level = models.PositiveIntegerField(blank=False, unique=True)
name = models.CharField(max_length=255, blank=False , unique=True)
description = models.TextField(blank=True)
class Meta:
verbose_name = _("Badge")
verbose_name_plural = _("Badges")
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse("Badge_detail", kwargs={"pk": self.pk})
""" Requirement Model for requirements """
class Requirement(models.Model):
number = models.PositiveIntegerField(blank=False)
badge = models.ForeignKey(Badge, on_delete=models.CASCADE)
name = models.CharField(max_length=255)
description = models.TextField(blank=True)
class Meta:
verbose_name = _("Requirement")
verbose_name_plural = _("Requirements")
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse("Requirement_detail", kwargs={"pk": self.pk})
In My view I try to join both tables and retrieve. It is,
""" ajax requirements in requirements table """
def get_requirements(request):
requirements = Requirement.objects.all().select_related('badge').values()
print(requirements)
return JsonResponse(list(requirements), safe=False)
The result is,
to the frontend,
to the backend,
Why does it not give me both tables' values?
Best way to achieve that is using Serializers which are the key component to deal with transforming data from models to JSON and the inverse:
To use this approach you can create the following serializers:
yourapp.serializers.py
from rest_framework.serializers import ModelSerializer
from yourapp.models import Requirement, Badge
class BadgeSerializer(ModelSerializer):
class Meta:
model = Badge
fields = '__all__'
class RequirementSerializer(ModelSerializer):
badge = BadgeSerializer()
class Meta:
model = Requirement
fields = '__all__'
After that you should go to your views.py file and do the following changes:
from yourapp.serializers import RequirementSerializer
def get_requirements(request):
reqs = Requirement.objects.select_related('badge')
return JsonResponse(RequirementSerializer(reqs, many=True), safe=False)
In this way you will have a more flexible way to add or remove fields from the serializer, and your application is also going to be more decoupled and easy to maintain.

How to save MultipleChoiceField to db

I want to create a settings page where a user can select multiple values of skills they have. It will have a main category and then subcategories. I need to save those into my database, so I can query them and show their selected skillset again.
I know how to create the MultipleChoiceField but not how to save them to the database. How would I go on about that?
Forms.py
from django import forms
class skills(forms.Form):
jobs = [
('Håndværker', (
('Gulv', 'Gulv'),
('Væg', 'Væg'),
)
),
('Murer', (
('Mur', 'Mur'),
('blabla', 'blabla'),
)
),
]
job = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple,
choices=jobs)
Views.py
from .forms import skills
def index(request):
if request.method == 'POST':
form = skills(request.POST)
if form.is_valid():
picked = form.cleaned_data.get('job')
# do something with your results
else:
form = skills
return render(request, 'settings/index.html', {"form":form})
It currently looks like this when the page loads which is good. Next step is just how I would save it to the database, so I can display this again with their previous chosen values.
Since you don't have any models setup yet, you can look into django-multiselectfield, which would store the selected choices "as a CharField of comma-separated values". Then you'd just need to pass those values from your form.
Alternatively you can look into PostgreSQL's Array field.
I would recommend you have a Jobs model and a Skills Model. Then have a skills field on the job model which will be a ManyToManyField to the Skills model. The form for this can then be autogenerated for you by Django as a ModelForm.
# Create your models here.
class Skill(models.Model):
name = models.CharField(max_length=20, null=False, blank=False)
def __str__(self):
return self.name
class Job(models.Model):
name = models.CharField(max_length=20, null=False, blank=False)
skills = models.ManyToManyField(Skill)
def __str__(self):
return self.name
class Person(models.Model):
name = models.CharField(max_length=20, null=False, blank=False)
skills = models.ManyToManyField(Skill)
def __str__(self):
return self.name
You can then add them to the db as
skill1 = Skill.objects.create(name="Skill One")
skill2 = Skill.objects.create(name="Skill Two")
skill3 = Skill.objects.create(name="Skill Three")
skill4 = Skill.objects.create(name="Skill Four")
job1 = Job.objects.create(name="Job One")
job1.skills.add(skill1)
job1.skills.add(skill2)
job2 = Job.objects.create(name="Job Two")
job2.skills.add(skill3)
job2.skills.add(skill4)
Have a form to display
class PersonForm(forms.ModelForm):
class Meta:
model = Person
fields = ["name", "skills"]
You can cutomize the form or the template to your linking
in models.py just create the field with CharField
from django.db import models
class UserProfileInfo(models.Model):
Gender = models.CharField(max_length=10,default='')
in forms.py just create CHOICE like below
class UserProfileInfoForm(forms.ModelForm):
YESNO_CHOICES = (('male', 'male'), ('female', 'female'))
Gender = forms.ChoiceField(choices=YESNO_CHOICES)
class Meta():
model = UserProfileInfo
fields = ('Gender',)
in views.py import this form and display it.
or you can definitely go with
https://pypi.org/project/django-multiselectfield/

Add multiple fields to django form

I am new to django and I'm making food recipe app. I want the users to be able to add their own recipe.
models.py
from django.db import models
from django.core.urlresolvers import reverse
class Recipe(models.Model):
def __unicode__(self):
return self.recipe_name
recipe_name = models.CharField(max_length=250)
category = models.CharField(max_length=50)
description = models.CharField(max_length=1000)
image = models.CharField(max_length=1000)
prep_time = models.CharField(max_length=250)
difficulty = models.CharField(max_length=50)
instructions_url = models.CharField(max_length=1000)
def get_absolute_url(self):
return reverse('detail', kwargs={'pk': self.pk})
class Ingredients(models.Model):
def __unicode__(self):
return self.ingredients
recipe = models.ForeignKey(Recipe, on_delete=models.CASCADE)
ingredients = models.CharField(max_length=1000)
views.py
class RecipeCreate(CreateView):
model = Recipe
fields = ['recipe_name', 'category', 'image', 'prep_time', 'difficulty', 'instructions_url']
At the moment my form display the fields only from my "class Recipe", but what i want is to have Ingredient field with option to add additional fields. Do you have any suggestions how to do this? Thanks!
It's going to be difficult to do that with the generic CreateView which is meant to create just one instance of a model.
What you want is a view (you could use the generic Django View) with a form (ModelForm) for your Recipe and a formset (see Django formsets) for multiple Ingredients forms. In your View's post method you then validate all the forms and save the data.
In your HTML, you'll need to create additional fields dynamically using javascript and update the number of formsets accordingly (in the formset's management form)

How to do field validation in django-import-export

Following is my model:
class Product(models.Model):
product_title = models.CharField(max_length=100, null=False,
verbose_name='Product title')
product_description = models.TextField(max_length=250,
verbose_name='Product description')
product_qty = models.IntegerField(verbose_name='Quantity')
product_mrp = models.FloatField(verbose_name='Maximum retail price')
product_offer_price = models.FloatField(verbose_name='Selling price')
I wanted to have a validation for product_offer_price field before save for which I had posted a QUESTION and it was answered with the working solution.
Validation needed is:
if product_offer_price > product_mrp:
raise ValidationError
Now the solution to above question works perfectly for the admin forms.
But, I have implemented django-import-export, in which I am importing Product Data in bulk in admin, and I need similar validation during bulk import.
How to achieve this?
Well, here was a little research process.
And finally I got it.
The trouble is avoiding ProductForm in import-export library.
Inside library import invoke method save() of instance, but if we raise ValidationError in Model (not in Form) = 500 with DEBUG = False, and traceback page with DEBUG = True.
So we should use "before_import" method in import_export Resource and "clean" method in django.forms Form.
admin.py
from forms import ProductForm
from models import Product
from import_export import resources
from import_export.admin import ImportExportActionModelAdmin
from django.forms import ValidationError
class ProductResource(resources.ModelResource):
class Meta:
model = Product
def before_import(self, dataset, using_transactions, dry_run, **kwargs):
for row in dataset:
if int(row[4]) < int(row[5]):
raise ValidationError('Product offer price cannot be greater than Product MRP. '
'Error in row with id = %s' % row[0])
class ProductAdmin(ImportExportActionModelAdmin):
list_display = ('product_title', 'product_description', 'product_qty', 'product_mrp', 'product_offer_price')
form = ProductForm
resource_class = ProductResource
admin.site.register(Product, ProductAdmin)
forms.py
from django import forms
from models import Product
class ProductForm(forms.ModelForm):
class Meta:
model = Product
exclude = [id, ]
def clean(self):
product_offer_price = self.cleaned_data.get('product_offer_price')
product_mrp = self.cleaned_data.get('product_mrp')
if product_offer_price > product_mrp:
raise forms.ValidationError("Product offer price cannot be greater than Product MRP.")
return self.cleaned_data
models.py
class Product(models.Model):
product_title = models.CharField(max_length=100, null=False, verbose_name='Product title')
product_description = models.TextField(max_length=250, verbose_name='Product description')
product_qty = models.IntegerField(verbose_name='Quantity')
product_mrp = models.FloatField(verbose_name='Maximum retail price')
product_offer_price = models.FloatField(verbose_name='Selling price')
An easier way might be to hook into the import/export workflow by adding a custom before_import_row method to your resource class:
class ProductResource(resources.ModelResource):
class Meta:
model = Product
def before_import_row(self, row, **kwargs):
if int(row[4]) < int(row[5]):
raise ValidationError('Product offer price cannot be greater than Product MRP. '
'Error in row with id = %s' % row[0])
here is another Simple Way For Django Rest Framework
def importcsv(request, company):
for row in dataset['company']:
if(row != company):
raise PermissionDenied("You do not have permission to Enter Clients in Other Company, Be Careful")

django ForeignKey model filter in admin-area?

Hi I need really very very simple example. First my models:
#This my student models
from django.db import models
SEX_CHOICES= (
('M', 'Male'),
('F', 'Female'),
)
class Students(models.Model):
student_name = models.CharField(max_length=50)
student_sex = models.CharField(max_length=8, choices=SEX_CHOICES)
student_city = models.Charfield(max_length=50)
student_bio = models.TextField()
def __unicode__(self):
return self.student_name
O.K. Let see my ClassRooms Model.
#This my ClassRooms models
from django.db import models
from myproject.students.models import *
class ClassRooms(models.Model):
class_number= models.CharField(max_length=50)
class_student_cities = models.ForeignKey(Students)
class_year = models.DateField()
def __unicode__(self):
return self.class_number
How can i show in the class_student_cities area the Students.student_city datas? I guess that about django-admin area. When i do it withclass_student_cities = models.ForeignKey(Students) i just see in that area the Students.student_name data (ex: John Smith). I want to see JUST Students.student_cities data (ex: NewYork). Can you give me a little example?
Should i use something like that:
class_student_cities = models.ForeignKey(Students.student_cities)
Many Thanks!
Try redifinition unicode method.
def __unicode__(self):
return self.student_city
So you'll see in the field student city.
Well, I tried to remake your application to set data with forms class. Something like this in admin.py in your application:
from django.contrib import admin
from django import forms
from myapp.models import *
class ClassRoomsAdminForm(forms.ModelForm):
class Meta:
model = ClassRoom
def __init__(self, *arg, **kwargs):
super(ClassRoomsAdminForm, self).__init__(*arg, **kwargs)
self.fields[' class_student_cities'].choices = [(csc.id,csc.student_city) for csc in Students.objects.all()
class ClassRoomsAdmin(admin.ModelAdmin):
form = ClassRoomsAdminForm
admin.site.register(ClassRooms,ClassRoomsAdmin)
Maybe you'll need to fix something, but I hope it will work. You will set init function to your forms, so in admin panel you set all choices to everything you keep in your Students model. csc.id you'll need to make this object iterable (cities aren't unique) and then you can choose everything from Students model to set in the field.