I am trying to implement an autocomplete search on a foreignkey field in my form. I have been through the docs but not sure what I need to do to get it working. I just get the normal dropdown box on the foreignkey field.
Here is my attempt:
settings.py
INSTALLED_APPS = (
'crispy_forms',
'autocomplete_light',
)
urls.py
url(r'^autocomplete/', include('autocomplete_light.urls')),
models.py
class Client(models.Model):
...
class Branch(models.Model):
client = models.ForeignKey(Client, related_name='clients')
...
forms.py
import autocomplete_light
class BranchForm(autocomplete_light.ModelForm):
class Meta:
model = Branch
autocomplete_fields = ('client')
exclude = ('creation', 'last_modified')
form.html
<form method="POST" action="">{% csrf_token %}
{{ form|crispy }}
<input class="btn btn-primary" type="submit" value="Submit" />
<button type="button" class="btn btn-danger">Cancel</button>
</form>
Figured it out in the end. Needed to register it.
autocomplete_light.register(Branch,
name = 'ClientAutocomplete',
choices = Client.objects.all()
)
class ClientForm(forms.ModelForm):
class Meta:
model = Client
exclude = ('creation', 'last_modified')
class BranchForm(autocomplete_light.ModelForm):
class Meta:
model = Branch
autocomplete_names = {'client':'ClientAutocomplete'}
exclude = ('creation', 'last_modified')
Related
My models.py and this is my model for photos.
# home photo page
class Photos(models.Model):
photo_title = models.CharField(max_length=50, blank=False)
photo_description = models.CharField(max_length=50, blank=False)
photo_date = models.DateField(blank=False)
photo_location = models.CharField(max_length=50, blank=False)
photo_file = models.FileField(upload_to='photos', blank=False)
def __str__(self):
return self.photo_title
My forms.py this is the model form I made to render it as a form.
class UploadPhotosForm(forms.Form):
class Meta:
model = Photos
fields = '__all__'
my views.py these are my relavent imports and section I coded in view file.
from .forms import CampForm, ProjectForm, HikeForm, UploadPostsForm, UploadPhotosForm
posts = UploadPostsForm()
photo = UploadPhotosForm()
print(photo.as_p())
here this code should print the form as text into console isn't it?
But I don't have any console output. It seems like the nothing has been initialized to the photo variable isn't it?
I do not have any clue what happened.
context = {
'title': 'manage_wall',
'posts': posts,
'photo': photo,
}
return render(request, 'manager/manage_wall.html', context)
My template
{% block content %}
<div class="container">
<div class="row">
<div class="col">
<form action="" method="post">
{% csrf_token %}
{{photo.as_p}}
<input type="submit" value="Add">
</form>
</div>
<div class="col">
<form action="" method="post">
{% csrf_token %}
{{posts.as_p}}
<input type="submit" value=" Add">
</form>
</div>
</div>
</div>
{%endblock %}
As you can see here my photoForm is not rendering in the frontend can someone point out the mistake I have made not to render that form only while other forms are successfully rendering in the frontend. My Question is all other model forms rendered successfully why this is not displaying properly.
Your UploadPhotosForm is inherited from forms.Form(...)
class which does not contain model in Meta class so instead of inheriting from forms.Form class inherit from form.ModelForm(...)
here is final version of your code
class UploadPhotosForm(forms.ModelForm):
class Meta:
model = Photos
fields = '__all__'
I found the answer in models.py it should be forms.ModelForm
class UploadPhotosForm(forms.ModelForm):
class Meta:
model = Photos
fields = '__all__'
it is not rendering unless it is a ModelForm
I am not able to create an detail and update view using the <pk> and <pk>/update/, this is my url paths.
urlpatterns = [
path('',views.IndexView.as_view(), name='index'),
path('form/',views.CompanyView.as_view(),name='company'),
path('toy/',views.ToyView.as_view(),name='toy'),
path('int:pk>/',views.CompanyDetailView.as_view()),
path('int:pk>/update/',views.CompanyUpdateView.as_view())
]
my views looks like this,
class CompanyUpdateView(generic.UpdateView):
model = Company
fields = '__all__'
success_url = '/company'
class CompanyDetailView(generic.DetailView):
model = Company
fields = '__all__'
class CompanyView(generic.CreateView):
model = Company
template_name = 'company/company.html'
fields = '__all__'
success_url = '/company'
models.py is
class Company(models.Model):
company_name = models.CharField(max_length=50)
location = models.CharField(max_length=50)
email_id = models.EmailField()
def __str__(self):
return self.company_name
class Toys(models.Model):
toy_name = models.CharField(max_length=50)
company = models.ForeignKey(Company,on_delete=models.CASCADE,blank=True,null=True)
price = models.IntegerField()
This is the template used to in the CreateView and UpdateView since I am using a ModelForm
<form method="post">
{% csrf_token %}
<fieldset>
<legend>
<h2> Company Form </h2>
</legend>
{{ form.as_p }}
</fieldset>
<input type="submit" value="Submit" />
</form>
Create view is working. When I got to a url company/1/ or company/1/update I get a 404 error. What would be the reason for it and how to solve this
I want to implement django admin filters in my custom template can any body from you help me in resolving this issue i will appreciate. i am getting this error ...... name 'AddFilter' is not defined...
models.py
from django.db import models
class Product(models.Model):
name = models.CharField(max_length=255)
price = models.DecimalField()
description = models.TextField()
release_date = models.DateField()
filters.py
import django_filters
class ProductFilter(django_filters.FilterSet):
name = django_filters.CharFilter(lookup_expr='iexact')
class Meta:
model = Product
fields = ['price', 'release_date']
views.py
def filt_page(request):
filter = AddFilter(request.GET, queryset=Add.objects.all())
print (filter)
return render_to_response('filt_page.html',{'filter':filter})
template
<form action="" method="get"> {% csrf_token %}
{{ filter.form.as_p }}
<input type="submit" />
</form>
{% for obj in filter %}
{{ obj.name }}<br />
{% endfor %}
You've called an undefined class in your views.py
class name in filters.py is 'ProductFilter' but you've called 'AddFilter' in views.py
Also the model name in your filter is undefined, you've used 'Add' instead of 'Product'
Try
filter = ProductFilter(request.GET, queryset=Product.objects.all())
Upon loading, it looks like the image above. In the middle, there is an upload file form done through crispyforms.
This is how I want it to look like upon loading the website. Instead, I need to click a button before this upload part of the form shows up.
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4" >tul.ai</legend>
{{ form|crispy }}
</fieldset>
<div class="form-group">
<button name = "upload_image" class="btn btn-outline-info" type="submit">View Image</button>
<button name = "upload_pdf" class="btn btn-outline-info" type="submit">View PDF</button>
</div>
</form>
Above is the HTML with the crispyform.
from django import forms
from .models import Photo, PDF
class PhotoForm(forms.ModelForm):
class Meta:
model = Photo
fields = ['image']
class PDFForm(forms.ModelForm):
# file = forms.FileField()
class Meta:
model = PDF
fields = ['file']
Above is the code for the forms themselves.
from django.db import models
from PIL import Image
class Photo(models.Model):
image = models.ImageField(upload_to='imgs')
def save(self):
super().save()
img = Image.open(self.image.path)
if self.image.height > 2200 or self.image.width > 1700:
output_size = (1700, 2200)
img.thumbnail(output_size)
img.save(self.image.path, quality = 100)
class Meta:
verbose_name = 'photo'
class PDF(models.Model):
file = models.FileField(upload_to='pdfs')
def save(self):
super().save()
class Meta:
verbose_name = 'pdf'
This is the models.py file.
I did the upload of an image with some information using a form with Django Rest Framework, it works but displayed using DRF default template, I want to use my own template so that i can add more button and link.
When i looked at that, it's about creating my template "api.html" in a folder rest_framework in my folder of templates but i don't know what i can put in the template content that i want to create.
My views :
class ImageViewSet(viewsets.ModelViewSet):
queryset = Video.objects.all()
serializer_class = ImageWatermarkSerializer
filter_backends = (filters.DjangoFilterBackend,filters.OrderingFilter,)
filter_fields = ('completed',)
ordering = ('-date_created',)
For the serializer :
class ImageWatermarkSerializer(serializers.ModelSerializer):
image = serializers.FileField(max_length=None,use_url=True)
class Meta:
model = Image
fields = ('id', 'image_name', 'image_desc', 'date_created', 'image', 'completed', 'size')
My models :
class Video(models.Model):
image_name = models.CharField(max_length=50)
image_desc = models.TextField(max_length=200)
completed = models.BooleanField(default=False)
date_created = models.DateTimeField(auto_now=True)
image = models.FileField(upload_to='imgs', default='/home/None/No-image.mp4')
size = models.IntegerField(default=10)
def __str__(self):
return "%s" % self.image_name
In my urls.py:
router = routers.DefaultRouter()
router.register(r'upl', views.ImageViewSet)
urlpatterns = [
url(r'^upload/', include(router.urls)), ]
As you already created your api.html file, you need to define template_name in your api view.
renderer_classes = [TemplateHTMLRenderer]
template_name = 'api.html'
And in your api.html
{% load rest_framework %}
<form class="form-horizontal" action="{% url 'upload' %}" method="post" novalidate enctype="multipart/form-data">
{% csrf_token %}
# this will include your serializer fields
{% render_form serializer %}
# Here you can customize your buttons
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default">Sign in</button>
</div>
</div>
</form>
If you need to change the image field styles DRF gives you style attribute,
image = serializers.FileField(
style={'template': 'app/image.html'}
)
Find more details at docs