Django Foreign Key Dropdown Filter - python

I have a model called Listing which is basically a job listing posted by my users. One of the fields is a Foreign Key called Address (since a user can have multiple addresses). Here is my models.py:
class JobListing(models.Model):
title = models.CharField(max_length=250)
description = models.TextField()
customer = models.ForeignKey('CustomerAuth.CustomerProfile')
address = models.ForeignKey('CustomerAuth.Address')
Here is my forms.py:
class JobListingForm(forms.ModelForm):
class Meta:
model = JobListing
fields = ['title', 'description', 'address', 'customer']
and finally the relevant parts of my views.py:
def create_listing(request):
form = JobListingForm(request.POST or None)
if form.is_valid():
listing = form.save(commit=False)
listing.save()
current_user = CustomerProfile.objects.get(user=request.user)
listing.customer = current_user
listing.save()
return HttpResponseRedirect('/listings/id/%s' % listing.id)
context_dict = {'form': form}
return render(request, 'listing/create-listing.html', context_dict)
As it currently stands when a user selects an address from the dropdown it shows everyones address. Is there anyway I can filter it so that only the addresses entered by that user is shown.

forms.py
class JobListingForm(forms.ModelForm):
class Meta:
model = JobListing
fields = ['title', 'description', 'address', 'customer']
def __init__(self, user, *args, **kwargs):
super(JobListingForm, self).__init__(*args, **kwargs)
self.fields['address'].queryset = Address.objects.filter(user=user)
in your views file
def create_listing(request):
user = request.user
form = JobListingForm(user, request.POST or None) #pass request.user

try something like this
model1.objects.get(pk=1).model2_set.all()

Related

How to assign a user to an employee in Django

I am a beginner in django and trying to create a web application for my task.
I am trying to assign a user to every to employee.
The idea is that user(in my class Employee) brings a list of user options that have not yet been assigned to the new employee to be registered.
My model:
class Employee():
name = models.CharField(max_length=100)
job = models.CharField(max_length=30)
user = models.OneToOneField(User,on_delete=models.CASCADE)
def __str__(self):
return'{}'.format(self.name,self.job,self.user)
My form:
class EmployeeForm(forms.ModelForm):
user= forms.ModelChoiceField(queryset=User.objects.filter(id=Employee.user))
class Meta:
model = Employee
fields = [
'name',
'job',
'user'
]
My view:
def register_employee(request):
if request.method == 'POST':
form = EmployeeForm(request.POST)
if form.is_valid():
form.save()
return redirect('/')
return redirect('list_employee')
else:
form = EmployeeForm()
return render(request, 'employee/employee_form.html',{'form': form})
I guess your code to be modified as,
class EmployeeForm(forms.ModelForm):
user= forms.ModelChoiceField(queryset=User.objects.filter(employee=None))
Please try the above.

Make a choices list for forms.py after receiving data from views.py in django

So this is the scenario. I allow my user to first input their vehicle brand with one form and then use another form to list down the models available for that vehicle brand. The information on the vehicles and the brands is stored in my database.
Refer to this image to get a better idea:
And this is my views.py:
def driver_dashboard_trip_brand (request, brand):
if request.method == "POST":
form = AddVehicleForm(request.POST)
else:
form = AddVehicleForm()
brands = VehicleBrand.objects.all()
context = {
"form":form,
"brands":brands,
"chosen_brand":brand
}
return render (request, "app/driver_dashboard.html", context)
And my forms.py:
class AddVehicleForm(forms.ModelForm):
model = forms.ModelChoiceField(queryset=VehicleModel.objects.all())
vehicle_colour = forms.ChoiceField(choices=COLOURS)
vehicle_number = forms.CharField(max_length=8, widget=forms.TextInput(attrs={'placeholder': 'eg: CAB-1234'}))
class Meta:
model = Vehicle
fields = ['model', 'vehicle_colour', 'vehicle_number']
So in order to set a query in the forms.py, I would first need to send the data from views.py to forms.py, and then I also need to do a query.
So my question is how can I query for all the car models from the VehicleModel database and create choices attribute for the form, once the user chooses the car brand.
My models.py...
class VehicleModel (models.Model):
brand = models.ForeignKey(VehicleBrand, on_delete=models.CASCADE)
model = models.CharField(max_length=30)
def __str__ (self):
return f"{self.brand} - {self.model}"
Its honestly not so hard, i kinda figured it out...
So this is my forms.py...
class AddVehicleForm(forms.ModelForm):
def __init__(self, brand=None, *args, **kwargs):
super(AddVehicleForm, self).__init__(*args, **kwargs)
self.fields['model'].queryset = VehicleModel.objects.filter(brand=brand)
model = forms.ModelChoiceField(queryset=VehicleModel.objects.all())
vehicle_colour = forms.ChoiceField(choices=COLOURS)
vehicle_number = forms.CharField(max_length=8, widget=forms.TextInput(attrs={'placeholder': 'eg: CAB-1234'}))
class Meta:
model = Vehicle
fields = ['model', 'vehicle_colour', 'vehicle_number']
class AddVehicleFormPost(forms.ModelForm):
model = forms.ModelChoiceField(queryset=VehicleModel.objects.all())
vehicle_colour = forms.ChoiceField(choices=COLOURS)
vehicle_number = forms.CharField(max_length=8, widget=forms.TextInput(attrs={'placeholder': 'eg: CAB-1234'}))
class Meta:
model = Vehicle
fields = ['model', 'vehicle_colour', 'vehicle_number']
Where the form AddVehicleForm allowed me to send the parameter as shown by typing form = AddVehicleForm(VehicleBrand.objects.filter(brand=brand).first()) in my views.py, but then when I wanted to save my form I needed to create another form in the forms.py without taking any query which is shown in AddVehicleFormPost.
Then i casually did,
if request.method == "POST":
form = AddVehicleFormPost(request.POST)
if form.is_valid():
In my views.py...
Here you have a nice tutorial on how to create dependent fields, you need to understand what's going on on the Server, and what's going on on the Client

How do I remove this error message in ModelForm?

I'm trying to create a way to update an item of the database that has the fields CharField and ForeignKey. I want to pass the original values so that they don't have to be manually entered for each field every time, but this gives me a "Select a valid choice. That choice is not one of the available choices." warning for the group field. How do I remove this warning message?
Setting the error message (in ModelForm) to something else manually still displays an empty (unordered) list item. Setting the form in UpdateUserView to form = UserForm() gets rid of the errors, but doesn't pass default values to the form.
models.py
class User(models.Model):
username = models.CharField(max_length=50)
group = models.ForeignKey(Group, on_delete=models.CASCADE)
class Group(models.Model):
name = models.CharField(max_length=20)
description = models.CharField(max_length=200)
forms.py
class UserForm(forms.ModelForm):
class Meta:
model = User
fields = ['username', 'group']
views.py
class UpdateUserView(TemplateView):
template_name = 'update_user.html'
def get(self, request):
user_id = int(request.GET.get('user_id'))
user = User.objects.get(id=user_id)
default_name = getattr(user, 'username')
default_group = getattr(user, 'group')
form = UserForm({'username': default_name, 'group': default_group})
return render(request, self.template_name, {'form': form, 'user': user})
End Result
You have to use initial argument like this:
class UpdateUserView(TemplateView):
template_name = 'update_user.html'
def get(self, request):
user_id = int(request.GET.get('user_id'))
user = User.objects.get(id=user_id)
form = UserForm(initial={'username': user.username, 'group': user.group.id})
return render(request, self.template_name, {'form': form, 'user': user})
Look I'm using group: user.group.id here, since the model Field you are referencing there in your form is a ForeignKey.
I hope this help.

Form submission not generating new Post object

I'm currently creating a Social platform with Django. Right now, I'm developing their Dashboard and want endusers to be able to publish their own posts. This is my Post model:
class Post(models.Model):
user = models.ForeignKey(User)
posted = models.DateTimeField(auto_now_add=True)
content = models.CharField(max_length=150)
Likes = models.IntegerField(default=0)
def __str__(self):
return self.user.username
My Form for the Post model:
class Post_form(forms.ModelForm):
class Meta:
model = Post
fields = (
'content',
]
def __init__(self, *args, **kwargs):
super(Post_form, self).__init__(*args, **kwargs)
self.fields['content'].label = ""
self.fields['content'].widget.attrs={
'id': 'id_content',
'class': 'myCustomClass',
'name': 'name_content',
'placeholder': 'What are you thinking about?',
}
When the form gets submitted, it correctly generates a POST request with the value of the content field. When I save my form in the view, no new post gets generated. What am I doing wrong?
My views.py:
def dashboard_view(request):
if request.POST:
form = Post_form(data=request.POST, instance=request.user)
if form.is_valid():
form.save() // <- no new post gets generated after saving
return redirect(reverse('dashboard'))
else:
return redirect(reverse('settings'))
else:
form = Post_form
gebruikers = User.objects.all()
all_posts = Post.objects.all().order_by('-posted')
return render(request, 'Dashboard/index.html', {'gebruiker':gebruikers, 'posts':all_posts, 'form': form},)
You can't pass the user as the instance parameter to a Post form. You should omit that argument and assign the user on the actual Post instance returned from save.
form = Post_form(data=request.POST)
if form.is_valid():
post = form.save(commit=False)
post.user = request.user
post.save()

Django forms selecting data based on request user

I am developing a django application which has a form for creating ingredients. The form contains a dropdown for selecting Recipes. When a user creates an ingredient, in the dropdown, I want that only those recipes should appear that are created by the same user.
Here is my code:
#forms.py
class IngredientForm(forms.ModelForm):
primal = forms.BooleanField()
class Meta:
model = Ingredient
fields = ('recipe_id', 'title', 'instructions', 'rules')
#models.py
class Recipe(models.Model):
user = models.ForeignKey('auth.User')
title = models.CharField(max_length=500)
description = models.TextField(max_length=500)
rules = models.TextField(max_length=500,blank=True)
def __str__(self):
return self.title
class Ingredient(models.Model):
user = models.ForeignKey('auth.User')
recipe_id = models.ForeignKey(Recipe, on_delete=models.CASCADE)
title = models.CharField(max_length=500)
instructions = models.CharField(max_length=500)
rules = models.TextField(max_length=500,blank=True)
primal = models.CharField(default='0',max_length=500,blank=True)
def __str__(self):
return self.title
#views.py
def create_ingredient(request):
if request.method == 'POST':
form = IngredientForm(request.POST)
if form.is_valid():
current_user = request.user
data = form.cleaned_data
ingredient_data=Ingredient.objects.create(user=current_user, recipe_id=data['recipe_id'],title=data['title'], primal=data['primal'], instructions=data['instructions'], rules=data['rules'])
ingredient_data.save()
ingredient = Ingredient.objects.get(pk = ingredient_data.pk)
return redirect('ingredient_detail', pk=ingredient.pk)
else:
messages.error(request, "Error")
return render(request, 'create_ingredient.html', {'form': IngredientForm })
The problem is that right now, when the user tries to select a recipe, the recipes created by all users of the site appear in the 'recipe_id' dropdown. He should only be able to see recipes in the dropdown that are created by himself. Any ideas how to do it?
UPDATE FROM ANSWER:
If I use this:
...
if request.method == 'POST':
form = IngredientForm(current_user=request.user, request.POST)
if form.is_valid():
...
it gives me this syntax error: non-keyword arg after keyword arg in this line form = IngredientForm(current_user=request.user, request.POST)
UPDATE#2:
If I use:
...
if request.method == 'POST':
form = IngredientForm( request.POST,current_user=request.user)
if form.is_valid():
...
It gives me error: __init__() got multiple values of argument 'current.user'
If I use:
...
if request.method == 'POST':
form = IngredientForm( request.POST)
if form.is_valid():
...
It gives me error: 'QueryDict' object has no attribute 'id'
UPDATE # 3:
After implementing the latest update from answer. It gives me error name 'current_user' is not defined
in the following piece of code:
def create_ingredient(request):
form = IngredientForm(current_user=request.user)
In the model form you can do this:
class IngredientForm(ModelForm):
primal = forms.BooleanField()
class Meta:
model = Ingredient
fields = ('recipe_id', 'title', 'instructions', 'rules')
def __init__(self, current_user, *args, **kwargs):
super(IngredientForm, self).__init__(*args, **kwargs)
self.fields['recipe_id'].queryset = self.fields['recipe_id'].queryset.filter(user=current_user.id)
then instantiate the form like so
form = IngredientForm(current_user=request.user)
EDIT #1:
Passing in the user to the POST request form:
if request.method == "POST":
form = IngredientForm(request.POST, current_user=request.user)
if form.is_valid():
....
EDIT #2:
Try changing the init decleration to what is below and pop the user from the kwargs:
def __init__(self, *args, **kwargs):
current_user = kwargs.pop('current_user', None)
super(IngredientForm, self).__init__(*args, **kwargs)
if current_user:
self.fields['recipe_id'].queryset = self.fields['recipe_id'].queryset.filter(user=current_user.id)
I think this might solve your problems, leave the rest of the code the same as my answer above (where you create the forms)

Categories

Resources