I have made a Django Form using Django Crispy Forms. I used the Foreign Key concept to display dropdowns in my page. I would like the first option of the dropdown ('Choose..') to be shown to the user but he/she must not be able to select it.
It is very easy to do with JavaScript but I'm not sure how to do it with Django.
My page with the dropdowns
I am also attaching the code for my forms.py and models.py.
models.py
from django.db import models
from django import forms
class Organization(models.Model):
orgname = models.CharField(max_length = 100, blank=True)
def __str__(self):
return str(self.orgname)
class Team(models.Model):
teamID = models.AutoField(primary_key=True)
teamName = models.CharField(max_length = 100, blank=True)
org = models.ForeignKey(Organization, on_delete=models.CASCADE)
def __str__(self):
return str(self.teamName)
class AgileTeam(models.Model):
agileTeamID = models.AutoField(primary_key=True)
agileTeamName = models.CharField(max_length = 100, blank=True)
org = models.ForeignKey(Organization, on_delete=models.CASCADE)
team = models.ForeignKey(Team, on_delete=models.CASCADE)
def __str__(self):
return str(self.agileTeamName)
class Employee(models.Model):
name = models.CharField(max_length=100)
assoc_id = models.CharField(max_length=10)
username = models.CharField(max_length=50, blank=True)
password = models.CharField(max_length=50, blank=True)
organization = models.ForeignKey(Organization, on_delete=models.CASCADE)
team = models.ForeignKey(Team, on_delete=models.CASCADE)
agile_team = models.ForeignKey(AgileTeam, on_delete=models.CASCADE)
forms.py
from django import forms
from django.forms import ModelForm
from .models import Organization, Team, AgileTeam, Employee
class EmployeeForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput(render_value = True))
class Meta:
model = Employee
fields = ('name', 'assoc_id', 'username', 'password', 'organization', 'team', 'agile_team',)
labels = {
'name':'Name',
'assoc_id':'Associate ID',
'username': 'Username',
'password': 'Password',
'organization':'Organization Name',
'team': 'Team Name',
'agile_team': 'Agile Team'
}
def __init__(self, *args, **kwargs):
super(EmployeeForm,self).__init__(*args, **kwargs)
# Code to make fields optional and to set the first option of dropdown as "Choose.."
self.fields['organization'].required = False
self.fields['organization'].empty_label = "Choose.."
self.fields['team'].required = False
self.fields['team'].empty_label = "Choose.."
self.fields['agile_team'].required = False
self.fields['agile_team'].empty_label = "Choose.."
This is my first question on StackOverflow. I hope I have been able to explain my problem properly.
Thanks in advance!
May the force be with you.
Related
Each model is chain-linked to the previous model. I make one form to fill in, since all the models are linked. When I try to link a model address to a project, an error appears
NOT NULL constraint failed: crm_project.address_id
/crm/views.py, line 39, in add_project
form_project.save()
Models
class City(models.Model):
obl = models.CharField(max_length=255, choices=REGIONS, default="24", verbose_name="Регион")
name = models.CharField(max_length=128, verbose_name="Город")
population = models.IntegerField()
def __str__(self):
return self.name
class Address(models.Model):
city = models.ForeignKey(City, on_delete=models.PROTECT, verbose_name="Город")
street = models.CharField(max_length=255, verbose_name="Улица")
numb = models.CharField(max_length=64, verbose_name="Номер дома")
def __str__(self):
return f"{self.street}, {self.numb}"
class Project(models.Model):
manager = models.ForeignKey(User, on_delete=models.PROTECT, verbose_name="Сотрудник")
address = models.ForeignKey(Address, on_delete=models.PROTECT, verbose_name="Адрес")
# another fields
class ProjectDetail(models.Model):
project = models.OneToOneField(Project, on_delete=models.CASCADE, verbose_name="Проект")
# another fields
Forms
class AddressForm(forms.ModelForm):
class Meta:
model = Address
fields = ["city", "street", "numb"]
def __init__(self, *args, **kwargs):
city = kwargs.pop("city", "")
super(AddressForm, self).__init__(*args, **kwargs)
self.fields["city"] = forms.ModelChoiceField(queryset=City.objects.all())
class ProjectForm(forms.ModelForm):
class Meta:
model = Project
fields = ["file", "sq", "rent_tax"]
class ProjectDetailForm(forms.ModelForm):
class Meta:
model = ProjectDetail
exclude = ['project', 'comment', 'resume', 'complite', 'created_at']
Views
def add_project(request):
form_address = AddressForm(request.POST or None)
form_project = ProjectForm(request.POST or None)
form_detail = ProjectDetailForm(request.POST or None)
if request.method == 'POST':
if form_address.is_valid() and form_project.is_valid() and form_detail.is_valid():
address = form_address.save(commit=False)
form_project.manager = request.user
form_project.address = address
project = form_project.save(commit=False)
form_detail.project = project
form_address.save()
form_project.save()
form_detail.save()
context = {'form_address':form_address, 'form_project':form_project, 'form_detail':form_detail,}
return render(request, 'crm/project_form.html', context)
in your ProjectForm you specified these fields only fields = ["file", "sq", "rent_tax"]
but as per Your Model:
class Project(models.Model):
manager = models.ForeignKey(User, on_delete=models.PROTECT, verbose_name="Сотрудник")
address = models.ForeignKey(Address, on_delete=models.PROTECT, verbose_name="Адрес")
There two fields are null=FalseMeans every instance of Project must have these Values which you're not providing in the ProjectForm
to handle this error you can do 2 things as per your need.
replace this form with this:
class ProjectForm(forms.ModelForm):
class Meta:
model = Project
fields = '__all__"
or another option which is not how you should use foreign keys.
change your class with this and makemigrations and migrate again:
class Project(models.Model):
manager = models.ForeignKey(User, on_delete=models.PROTECT,null=True, blank=True, verbose_name="Сотрудник")
address = models.ForeignKey(Address, on_delete=models.PROTECT, null=True, blank=True,verbose_name="Адрес")
Working on a project that I am stumped on and I can't seem to find a good solution to this. An overview of the problem I need to resolve. I have 3 models (Games, GameRoles, and Groups) I have a defined list of games and a user can create a group from that list. The games also have roles associated with them. So the idea is I want a user to create a group based on a game from my game model, each game has different roles associated with it. When the user creates a group I want those roles to display in a checkbox field so they can add these roles if they need them.
My problem is I can't seem to find a good way to do this. I read the docs and I think what I need is an Iterating relationship choice class in my forms.py
Games model.py
from django.db import models
from django.db.models.aggregates import Max
from django.db.models.fields.related import ForeignKey
# Create your models here.
class Game(models.Model) :
GENRE_CHOICES = [
('Action', 'Action'),
('Acion-Adventure', 'Action-Adventure'),
('Adventure', 'Adventure'),
('MMO', 'MMO'),
('Puzzle', 'Puzzle'),
('Role Playing', 'Role Playing'),
('Simulation', 'Simulation'),
('Strategy', 'Strategy'),
('Sports', 'Sports')
]
RATING_CHOICES = [
('E', 'Everyone'),
('E10+', 'Everyone 10+'),
('T', 'Teen'),
('M', 'Mature 17+'),
('A', 'Adults Only 18+'),
('RP', 'Rating Pending')
]
PLATFORM_CHOICES = [
('Multi', 'Multi Platform'),
('PC', 'PC'),
('XBOX', 'XBOX'),
('Playstation', 'Playstation'),
('Nintendo', 'Nintendo')
]
name = models.CharField(max_length=200)
platform = models.CharField(max_length=20,
null=True,
choices=PLATFORM_CHOICES,
default='Select'
)
publisher = models.CharField(max_length=100)
genre = models.CharField(max_length=100,
null=True,
choices=GENRE_CHOICES,
default='Select'
)
rating = models.CharField(max_length=15,
null=True,
choices=RATING_CHOICES,
default='Select'
)
release_date = models.DateField()
tags = models.CharField(max_length=200)
picture = models.ImageField(
max_length=200,
default='games/default.png',
null=True,
upload_to='games/'
)
is_new = models.BooleanField(null=True)
is_popular = models.BooleanField(null=True)
is_featured = models.BooleanField(null=True)
def __str__(self):
return self.name
class GameRole(models.Model):
game = models.ForeignKey(Game, on_delete=models.CASCADE)
role = models.CharField(max_length=200)
def __str__(self):
return self.role
Group models.py
from django.contrib.auth.models import User
from django.db import models
from django.db.models.aggregates import Max
from games.models import Game, GameRole
# Create your models here.
class Group(models.Model):
name = models.CharField(max_length=200)
game = models.ForeignKey(Game, on_delete=models.CASCADE)
size = models.IntegerField(default=1)
total_size = models.IntegerField(null=True)
play_time = models.DateTimeField(null=True)
description = models.TextField(max_length=200)
is_full = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
discord = models.URLField(max_length=200, null=True)
user = models.ForeignKey(User, null=True, on_delete=models.CASCADE)
def __str__(self):
return self.name
class GroupRole(models.Model):
group = models.ForeignKey(Group, on_delete=models.CASCADE)
role = models.ForeignKey(GameRole, on_delete=models.CASCADE)
def __str__(self):
return self.role
forms.py
from django import forms
from django.contrib.auth.models import User
from django.forms import fields, widgets
from LFG.models import Group, GroupMembers, GroupRole
from games.models import Game, GameRole
class DateTimeInput(forms.DateTimeInput):
input_type = 'datetime-local'
class CheckboxInput(forms.CheckboxInput):
input_type = 'checkbox'
class RoleSelect(form.Select):
def creation_option(self, name, value, label, selected, index, subindex=None, attrs=None):
option = super().create_option(name, value, label, selected, index, subindex, attrs)
class GroupForm(forms.ModelForm):
game = forms.ModelChoiceField(queryset=Game.objects.all())
class Meta():
model = Group
fields = ['game', 'name']
class GroupTwoForm(forms.ModelForm):
ROLE_CHOICES = []
roles= forms.ModelMultipleChoiceField(ROLE_CHOICES)
class Meta():
model = Group
fields = ['name', 'total_size', 'play_time', 'description', 'discord']
widgets = {
'play_time':DateTimeInput(),
#'roles':CheckboxInput()
}
def role_display(game_id):
roles = GameRole.object.all()
for role in roles:
if role.game_id == game_id:
r = role
ROLE_CHOICES[r] = r
return ROLE_CHOICES
class GroupMemberForm(forms.ModelForm):
class Meta():
model = GroupMembers
fields = [ 'group', 'member', 'role']
views.py
#login_required(login_url='/login')
def create_group_2_view(request, group_id):
profile = request.user.userprofile
form_user = Group.objects.filter(pk=group_id).values('user')
formID = Group.objects.filter(pk=group_id).first()
roles = GameRole.objects.all()
print(form_user)
if request.method == 'POST':
form = GroupTwoForm(request.POST or None, instance=formID)
# if group_id == form.pk:
if form.is_valid():
form.save()
messages.success(request, 'Group created!')
return redirect('lfg')
else:
print(form.errors)
messages.error(request, form.errors)
return redirect('create-group-2', formID)
else:
form = GroupTwoForm(instance=formID)
context = {
'title':'Create a Group',
'year':datetime.now().year,
'profile':profile,
'form':form,
'roles':roles,
}
return render(request, 'lfg/create-group-2.html', context)
As you can see in forms.py I was attempting to create a role section class that will do this and then pass it to GroupTwoForm. Sorry if this is a bit confusing, still learning Django, if clarification is needed I will clarify.
I've set up my models, serializers and viewsets in my Django REST API to assign a search record to a particular user, and to associate all the relevant user's searches to their record in the User model. It was all working fine, but I'm now getting the TypeError error message (in the subject line of this question) when I try to create a new user. I've listed the relevant models, serializers and viewsets below. Please could anyone take a look and let me know where I'm going wrong? Any help would be very much appreciated.
User serializer:
class UserSerializer(serializers.ModelSerializer):
searches = serializers.PrimaryKeyRelatedField(many=True, queryset=SearchHistoryModel.objects.all())
class Meta:
model = User
fields = ('id', 'username', 'email', 'password', 'searches')
extra_kwargs = {'email': {
'required': True,
'validators': [UniqueValidator(queryset=User.objects.all())]
}}
def create(self, validated_data):
user = User.objects.create_user(**validated_data)
Token.objects.create(user=user)
return user
User viewset:
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = [permissions.AllowAny]
Search model:
class SearchHistoryModel(models.Model):
"""
Stores each user's search submission
"""
created_date = models.DateTimeField(auto_now_add=True)
owner = models.ForeignKey(User, related_name='searches', on_delete=models.CASCADE)
cpu_component_name = models.CharField(max_length=10, blank=False)
cpu_subcomponent_name = models.CharField(max_length=50, blank=False)
motherboard_name = models.CharField(max_length=20, blank=False)
gpu_component_name = models.CharField(max_length=10, blank=True, null=True)
gpu_subcomponent_name = models.CharField(max_length=50, blank=True, null=True)
gpu_subcomponent_quantity = models.PositiveIntegerField(default=0)
ram_component_name = models.CharField(max_length=15, blank=True, null=True)
ram_component_quantity = models.PositiveIntegerField(default=0)
ssd_component_name = models.CharField(max_length=15, blank=True, null=True)
ssd_component_quantity = models.PositiveIntegerField(default=0)
hdd_component_name = models.CharField(max_length=20, blank=True, null=True)
hdd_component_quantity = models.PositiveIntegerField(default=0)
optical_drive_name = models.CharField(max_length=15, blank=True, null=True)
class Meta:
verbose_name = 'Search'
verbose_name_plural = 'Searches'
ordering = ['owner', 'created_date']
def __str__(self):
return '{}\'s search choices'.format(self.owner)
Search serializer:
class SearchHistorySerializer(serializers.ModelSerializer):
"""
Serializes the user's search history data passed into the SearchHistoryModel
Associates each search with the relevant user
"""
owner = serializers.ReadOnlyField(source='owner.username')
class Meta:
model = SearchHistoryModel
fields = (
'id', 'created_date', 'owner', 'cpu_component_name', 'cpu_subcomponent_name',
'motherboard_name', 'gpu_component_name', 'gpu_subcomponent_name',
'gpu_subcomponent_quantity', 'ram_component_name', 'ram_component_quantity',
'ssd_component_name', 'ssd_component_quantity', 'hdd_component_name',
'hdd_component_quantity', 'optical_drive_name'
)
Search viewset:
class SearchHistoryViewSet(viewsets.ModelViewSet):
queryset = SearchHistoryModel.objects.all()
serializer_class = SearchHistorySerializer
permission_classes = [permissions.IsAuthenticated]
def perform_create(self, serializer):
serializer.save(owner=self.request.user)
In user = User.objects.create_user(**validated_data), validated_data contains a searches value which is an id.
But actually the ForeignKey is in the other sense : in Searches model, and to refer to a User instance, not the opposite.
To link a user to searches, it is not in User DB table that you write an id, but in Searches that you write a User id.
class UserSerializer(serializers.ModelSerializer):
(...)
def create(self, validated_data):
# Extract the value from 'validated_data'
search_ids = validated_data.pop('searches', None)
user = User.objects.create_user(**validated_data)
Token.objects.create(user=user)
# Update existing search instances
for search_id in search_ids:
Search.objects.filter(id=search_id).update(owner=user)
return user
models.py:
class Book(models.Model):
name = models.CharField(max_length=100)
description = models.TextField(max_length=500)
image = models.ImageField(height_field="height_field", width_field="width_field")
height_field = models.IntegerField(default=255)
width_field = models.IntegerField(default=255)
price = models.FloatField()
edition = models.CharField(max_length=100)
no_of_page = models.IntegerField()
country = models.CharField(max_length=50)
publication = models.ForeignKey(Publication, on_delete=models.CASCADE)
authors = models.ManyToManyField(Author, through='AuthorBook')
ratings = GenericRelation(Rating, related_query_name='books')
class AuthorBook(models.Model):
author = models.ForeignKey(Author, on_delete=models.CASCADE)
book = models.ForeignKey(Book, on_delete=models.CASCADE)
class Author(models.Model):
name = models.CharField(max_length=100)
biography = models.TextField(max_length=500)
image = models.ImageField(height_field="height_field", width_field="width_field")
height_field = models.IntegerField(default=255)
width_field = models.IntegerField(default=255)
serializers.py
class AuthorListSerializer(ModelSerializer):
url = author_detail_url
class Meta:
model = Author
fields = [
'url',
'id',
'name',
]
class BookCreateUpdateSerializer(ModelSerializer):
authors = AuthorListSerializer(many=True, read_only=True)
def create(self, validated_data):
#code
def update(self, instance, validated_data):
#code
class Meta:
model = Book
fields = [
'name',
'description',
'price',
'edition',
'no_of_page',
'country',
'publication',
'authors',
]
views.py
class BookCreateAPIView(CreateAPIView):
queryset = Book.objects.all()
serializer_class = BookCreateUpdateSerializer
I am working for implementing Django REST Framework. I have two models Book and Author. But django create api view don't show authors field drop down. I checked many solution DRF for many to many field. Please help me to show authors field and write create() and update function. If you see DRF api page, it will be clear.
This is because of read_only=True. Try to remove this argument for bookserializer's authors field:
class BookCreateUpdateSerializer(ModelSerializer):
authors = AuthorListSerializer(many=True)
Models:
class Applicant_Skill(models.Model):
user = models.ForeignKey(User)
#applicant = models.ForeignKey(Applicant)
skill = models.ForeignKey('skills_layer.Skill')
active = models.BooleanField(default=True)
class Job_Posting(models.Model):
company = models.ForeignKey('companies_layer.Company', default=-1)
job_posted_by = models.ForeignKey(User, default=-1)
job_title = models.CharField(max_length=100)
job_summary = HTMLField(blank=True)
job_details = HTMLField(blank=True)
no_of_openings = models.IntegerField(default=0)
tags = models.CharField(max_length=200)
experience_min = models.IntegerField(default=0)
experience_max = models.IntegerField(default=0)
job_location = models.ForeignKey('meta_data_layer.Location', blank=True, null=True)
qualification = models.ForeignKey('meta_data_layer.Qualification', default=-1)
specialization = models.ForeignKey('meta_data_layer.Specialization', default=-1)
nationality = models.ForeignKey('meta_data_layer.Nationality', default=-1)
live = models.BooleanField(default=True)
closing_date = models.DateField(default=datetime.date.today())
auto_renew = models.BooleanField(default=False)
active = models.BooleanField(default=True)
class Meta:
verbose_name = "job posting"
def __str__(self):
return self.job_title
Resource:
from tastypie.resources import ModelResource
from job_posting_layer.models import Job_Posting
from companies_layer.models import Company
from django.contrib.auth.models import User
import meta_data_layer
from tastypie import fields
class UserResource(ModelResource):
class Meta:
queryset = User.objects.all()
resource_name = 'user'
def dehydrate(self, bundle):
bundle.data['logged_user_id'] = bundle.request.user.id
return bundle
class JobListingResource(ModelResource):
#company = fields.ForeignKey(CompanyResource,'company', full=True)
#job_posted_by = fields.ForeignKey(UserResource,'job_posted_by', full=True)
company_name = fields.CharField(attribute="company__company_name", null=True)
company_id = fields.CharField(attribute="company__id", null=True)
user_first_name = fields.CharField(attribute="job_posted_by__first_name", null=True)
user_last_name = fields.CharField(attribute="job_posted_by__last_name", null=True)
user_id = fields.CharField(attribute="job_posted_by__id", null=True)
job_location = fields.CharField(attribute="job_location__location_name", null=True)
job_city = fields.CharField(attribute="job_location__city", null=True)
qualification = fields.CharField(attribute="qualification__qualification_degree", null=True)
specialization = fields.CharField(attribute="specialization__specialization_course", null=True)
nationality = fields.CharField(attribute="nationality__country_name", null=True)
class Meta:
queryset = Job_Posting.objects.all()
resource_name = 'jobs'
Today is the 1st day I am trying Tastypie so please be kind with me :(
The JobListingResource returns all the Job Listings. But I want to get only those Job Listings for which the Tags column contains values from the skill column of the logged in user.
Eg: If user "A" has logged in and has the following skills "python,django,jquery". I want the JobListingResource to return only those records which contains [python/django/jquery] in the tags column.
I'm assuming you know how to do the queries and just need to know where to do it in Tastypie. In your JobListResource override as follows:
def get_object_list(self, request):
# get all the jobs according to the queryset in Meta
base = super(JobListingResource, self).get_object_list(request)
# and add a filter so only users ones appear
user = request.user
skills = query to get all the skills for the user
return base.filter(filter to apply to JobPosting to only return jobs matching skills list)