Pass current product_id to a Model in Django - python

I'm trying to give django a try by developing a simple page where people can ask something about a product
This is my model, i can create products in the admin area, display the product page, and the form shows up with the fields email, and text.
class Product(models.Model):
category = models.ForeignKey(Category)
title = models.CharField(max_length=100)
text = models.TextField()
class Question(models.Model):
email = models.CharField(max_length=100)
product = models.ForeignKey(Product, default=?, editable=False)
date = models.DateTimeField(auto_now=True, editable=False)
text = models.TextField()
class QuestionForm(ModelForm):
class Meta:
model = Question
But i don't know how to tell the model which product id the question has to be saved to.
This is my views.py
# other stuff here
def detail(request, product_id):
p = get_object_or_404(Product, pk=product_id)
f = QuestionForm()
return render_to_response('products/detail.html', {'title' : p.title, 'productt': p, 'form' : f},
context_instance = RequestContext(request))
def question(request, product_id):
p = get_object_or_404(Product, pk=product_id)
f = QuestionForm(request.POST)
new_question = f.save()
return HttpResponseRedirect(reverse('products.views.detail', args=(p.id,)))
And the URL
urlpatterns = patterns('products.views',
(r'^products/$', 'index'),
(r'^products/(?P<product_id>\d+)/$', 'detail'),
(r'^products/(?P<product_id>\d+)/question/$', 'question')
)
Righ now it works if i put a "1" in the default attribute for the product foreign key in the question model (where the question mark is), it saves the question to the product id 1. But i don't know what to do to make it save to the current product.

You can either:
Send product_id as form value
Make product foreign key in your form a hidden field and set it's value to primary key value of the product in detail view. This way you don't need a product_id in your question view URL and arguments since the ID will be passed with POST data. (see link for examples)
Id would use this option, since you'd have cleaner question URL and you could do more validation in your form on the product.
or
Send product_id through URL
Use reverse in your detail view to build the form action attribute or use url template tag to build the action attribute in form template. This way you need product_id in your question URL and arguments but you don't need product field in your QuestionForm. Then in question view simply get the product instance and set it as FK value on Question.
Example:
Using url template tag in products/detail.html:
<form action="{% url question product.pk %}" method="post">
....
</form>
Or use reverse in detail view:
def detail(request, product_id):
p = get_object_or_404(Product, pk=product_id)
f = QuestionForm()
return render_to_response('products/detail.html', {
'title' : p.title,
'product': p,
'action': reverse("question", args=[p.pk,]),
'form' : f},
context_instance = RequestContext(request))
your template:
<form action="{{ action }}" method="post">
....
</form>
Either way your question view would need a line added which actually sets product instance to Question attribute:
def question(request, product_id):
...
new_question.product = p

Related

How to pass foreign key id to form? or link form to a foriegn key value DJango

I am trying to auto populate my form Student field with the name Carl Park. In short I want my form to use to automatically use the Object ID instead of having to manually select the name Carl Park from the student field drop down menu.
How do I automatically link my Model Form to a foriegn key ID and have the form auto populate based on that value.
Here is my current form, my models.py forms.py views.py and HTML
#models
class Teacher(models.Model):
name = models.CharField(max_length=75)
room = models.CharField(max_length=10)
bio = models.TextField()
class Student(models.Model):
teacher = models.ForeignKey('Teacher', on_delete=models.CASCADE)
name = models.CharField(max_length=75)
class Student_Performance(models.Model):
student = models.ForeignKey('Student', on_delete=models.CASCADE)
behavior_grade = models.CharField(max_length=1)
#form
class StudentPerfromanceForm(ModelForm):
class Meta:
model = Student_Performance
fields = ( "name", "behavior_grade")
#view
def student_details(request, id):
obj = get_object_or_404(Student,pk=id)
form = StudentPerfromanceForm()
if request.method == 'POST':
form = StudentPerfromanceForm(request.POST)
if form.is_valid():
form.save(commit=True)
return all_students_list(request) #pass success message
return render(request, 'class_roster/student_details.html', {'obj':obj, 'reviewForm':form})
#HTML
<form method="POST">
{% csrf_token %}
{{reviewForm.as_p}}
<input type="submit" value="Submit Review">
</form>
I want to more code informations.
anyway if you want set student automatically use object_id,
try
objects.get(query)
ex) ModelClassName.objects.get(pk=1)

django - CBV - pass in multiple values from url

I am utterly confused and mortified by CBVs, seeking for help.
So I've designed the model structure and decided the url patterns as following, but simply can't write a valid CBV to facilitate the urls:
models.py
class Category(models.Model):
'''Category for men's and women's items'''
men = models.BooleanField()
women = models.BooleanField()
name = models.CharField(max_length=100)
description = models.CharField(max_length=300, blank=True)
uploaded_date = models.DateTimeField(
auto_now_add=True, null=True, blank=True)
class Meta():
verbose_name_plural = 'Categories'
def __str__(self):
return ("Men's " + self.name) if self.men else ("Women's " + self.name)
class SubCategory(models.Model):
'''Sub-category for the categories (not mandatory)'''
category = models.ForeignKey(Category, on_delete=models.CASCADE)
name = models.CharField(max_length=100)
description = models.CharField(max_length=300, blank=True)
uploaded_date = models.DateTimeField(
auto_now_add=True, null=True, blank=True)
class Meta():
verbose_name = 'Sub-category'
verbose_name_plural = 'Sub-categories'
def __str__(self):
return ("Men's " + self.name) if self.category.men else ("Women's " + self.name)
class Item(models.Model):
'''Each item represents a product'''
category = models.ForeignKey(Category, on_delete=models.CASCADE)
subcategory = models.ForeignKey(
SubCategory, on_delete=models.CASCADE, null=True, blank=True)
name = models.CharField(max_length=100)
description = models.TextField(blank=True)
price = models.IntegerField(default='0')
discount = models.IntegerField(null=True, blank=True)
uploaded_date = models.DateTimeField(
auto_now_add=True, null=True, blank=True)
class Meta:
ordering = ['-uploaded_date']
def __str__(self):
return self.name
def discounted_price(self):
'''to calculate the price after discount'''
return int(self.price * (100 - self.discount) * 0.01)
class ItemImage(models.Model):
item = models.ForeignKey(Item, on_delete=models.CASCADE)
image = models.ImageField(upload_to='itemimages', null=True, blank=True)
urls.py
app_name = 'boutique'
urlpatterns = [
# show index page
path('', views.IndexView.as_view(), name='index'),
# show categories of products for men or women
path('<slug:gender>/', views.ItemListView.as_view(), name='show-all'),
# show a specific category for men or women
path('<slug:gender>/cat_<int:category_pk>/', views.ItemListView.as_view(), name='category'),
# show a specific subcategory under a specific category for men or women
path('<slug:gender>/cat_<int:category_pk>/subcat_<int:subcategory_pk>/', views.ItemListView.as_view(), name='subcategory'),
# show a specific item
path('item_<int:item_pk>/', views.ItemDetailView.as_view(), name='item'),
]
views.py
class IndexView(ListView):
'''landing page'''
model = Category
template_name = 'boutique/index.html'
context_object_name = 'categories'
class ItemListView(ListView):
'''display a list of items'''
# model = Category ??? what's the point of declaring model when get_context_data() ???
template_name = 'boutique/items.html'
context_object_name = 'categories'
paginate_by = 12
def get_object(self):
obj = get_object_or_404(Category, pk=self.kwargs.get('category_pk'))
return obj
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['categories'] = Category.objects.all() # for rendering nav bar data
return context
class ItemDetailView(DetailView):
'''display an individual item'''
# model = Item
template_name = 'boutique/item.html'
context_object_name = 'item'
def get_object(self):
return get_object_or_404(Item, pk=self.kwargs['item_pk'])
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['categories'] = Category.objects.all()
return context
items.html
<a href="{% url 'boutique:show-all' 'women' %}> link to categories of product for women </a>
<a href="{% url 'boutique:category' 'women' category.pk %}> link to a cat for women </a>
<a href="{% url 'boutique:subcategory' 'women' category.pk subcategory.pk %}> link to a subcat under a specific cat for women </a>
Essentially, as you can see, I'd like the ItemListView to render multiple url paths depending on what value passed into the CBV... I can do it (pass multiple values) in a FBV, however, utterly confused by the mechanism of the CBVs...
So if anyone could write an example ItemListView and according anchor url template tags (if mine are incorrect), it would be tremendulent!!! Thanks!!!
EDIT 1
class ItemListView(ListView):
'''display a list of items'''
model = Item
template_name = 'boutique/items.html'
# paginate_by = 12
def get_queryset(self):
# get original queryset: Item.objects.all()
qs = super().get_queryset()
# filter items: men/women
if self.kwargs['gender'] == 'women':
qs = qs.filter(category__women=True)
elif self.kwargs['gender'] == 'men':
qs = qs.filter(category__men=True)
if self.kwargs.get('category_pk'):
qs = qs.filter(category=self.kwargs.get('category_pk'))
if self.kwargs.get('subcategory_pk'):
qs = qs.filter(subcategory=self.kwargs.get('subcategory_pk'))
# print(qs)
return qs
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
# add categories for navbar link texts
context['categories'] = Category.objects.all()
if self.kwargs.get('gender') == 'women':
context['category_shown'] = Category.objects.filter(women=True)
if self.kwargs.get('gender') == 'men':
context['category_shown'] = Category.objects.filter(men=True)
if self.kwargs.get('category_pk'):
context['category_shown']=get_object_or_404(Category, pk=self.kwargs.get('category_pk'))
if self.kwargs.get('subcategory_pk'):
context['subcategory_shown']=get_object_or_404(SubCategory, pk=self.kwargs.get('subcategory_pk'))
# print(context)
return context
After FiddleStix' answer (I haven't gone thu bluegrounds thread yet), I tried and managed to make everything work except ItemDetailView.
The urls are working fine and the filtering of get_queryset function is working fine, however,
Question 1: I wonder this might not be DRY enough?! Nevertheless, it's working. so thanks!! But could it be dryer??
Question 2: when ItemDetailView runs, the urls appear to be correct, however, the page redirect to a page rendering all items from all categories...
class ItemDetailView(DetailView):
'''display an individual item'''
# model = Item
template_name = 'boutique/item.html'
def get_object(self):
print(get_object_or_404(Item, pk=self.kwargs.get('item_pk')))
return get_object_or_404(Item, pk=self.kwargs.get('item_pk'))
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
# add categories for navbar link texts
# context['categories'] = Category.objects.all()
print(context)
return context
Neither is the object nor the context being printed out... and it doesn't prompt any error, either. I must have made a silly mistake somewhere!!
Answer to Question 2:
view.py
class ItemDetailView(DetailView):
'''display an individual item'''
model = Item
template_name = 'boutique/item.html'
The DetailView class should be simple if no customisation is needed, the problem is in the urlpatterns:
url.py
urlpatterns = [
path('item_<int:pk>', view.ItemDetailView.as_view(), name='item'),
]
Always use <pk> as the value passed in DetailView as it's the default. I used item_<int:item_pk> as the path url. That's why I had to use get_object() to manually get the item object (to override the default get_object()). As #bluegrounds answer suggests that the reason Class-based Views work well is they save time, for the default functions they possess.
If you wish to use item_<int:item_pk>, CBV offers the flexibility as well: simply override pk_url_kwargs = 'item_pk' in the View class - Feel free to check my other question: DetailView - get_object function confusion for clarification. #neverwalkaloner 's answer is very straightforward.
So first things first, CBVs...
They work by having "default" behaviours built into each one of them. For the ListView class, take this example view:
class ArticleListView(ListView):
model = Article
along with an example urlpattern:
path('all-articles/', ArticleListView.as_view())
and that's it. This is all that is essential for a ListView to work. This ArticleListView view would look for a template called article_list.html and in it you can use the context variable object_list to access all the Article objects that the class gets for you without you having to write the QuerySet explicitly.
Of course you can change these values, and customize the QuerySet, and do all kinds of things, but for that you'll have to study the docs. I personally find ccbv much easier to read than the docs. So for example you can see in ccbv's page about ListViews that the context_object_name = None which defaults to object_list, as mentioned above. You can change that to, for example context_object_name = 'my_articles'. You could also set the template_name = 'my_articles.html' and that will override the default template name pattern of <model>_list.html.
Now, about your code,
If you're sure that you want your URL structure to stay like it is, you could have your class view as follows to get the functionality you need:
class ItemListView(ListView):
template_name = 'boutique/items.html'
context_object_name = 'categories'
paginate_by = 12
def get_queryset(self):
# This method should return a queryset that represents the items to be listed in the view.
# I think you intend on listing categories in your view, in which case consider changing the view's name to CategoryListView. Just sayin'...
# An instance of this view has a dictionary called `kwargs` that has the url parameters, so you can do the following:
# You need some null assertions here because of the way you've setup your URLs
qs = Categories.objects.filter(men=self.kwargs['gender'], pk=self.kwargs['category_pk'])
return qs
As you can see, we didn't set many things in this class view for it to work. Namely, we didn't set the model variable as we did previously. That's because we wouldn't need it. The part that uses that variable was in the default get_queryset() method and we've overridden that method. See CCBV for more info on the default implementation of get_queryset().
Now the template will be supplied with the objects from get_queryset(), under the name categories, because that's what we set context_object_name's value to be.
NOTE: The variable model is used in other places other than get_queryset() such as the default template_name. The default template name is derived from the model name and the template_name_suffix. So if you don't set the model variable, make sure to set the template_name manually.
I'm not sure about your application's logic but I think you should change the Category model to have only one Boolean field that denotes gender. For example men if it is True and women if it's False. That way a category can't be for both men and women at the same time (unless that is something you need), and it also can't be for neither, because currently you can have a category be false for the both gender fields, which doesn't really make sense.
I would actually suggest a completely different solution that involves CHOICES, as such:
gender = models.IntegerField(null=False, CHOICES=[(1,'Men'), (2,'Women'), (3,'Other'), (4,'Unisex')], default=3)
This would store a number in the database that denotes the gender, and in your app you'll only see the correlating string (gender) to that number.
I have not tried this code on my machine so I might have missed a few things, but I hope I clarified the overall workings of CBVs.
To answer you main question, your ItemList should set model=models.Item, as alluded to in the error message, because it is meant to be a list of items.
I would set up your urls.py so that /items/ or /item_list/ goes to ItemListView.as_view(). If you then want to filter your list of items, I would not do it by changing the URL to /items/women/. Instead, I would use a URL query string like /items/?gender=women. How to do that is explained here but basically:
class ItemListView(ListView):
model = Item
template_name = "item_list.html"
paginate_by = 100
def get_queryset(self):
filter_val = self.request.GET.get('gender', 'some_default')
queryset = Item.objects.filter(
... # You'll have to work this bit out
)
return queryset
def get_context_data(self, **kwargs):
context = super(MyView, self).get_context_data(**kwargs)
context['gender'] = self.request.GET.get('gender', 'some_default')
return context

How do I filter my model within itself twice in Django?

I'm looking for some help with filtering my model twice in Django.
This is my current model:
class Medarbejder(models.Model):
id = models.AutoField(primary_key=True)
slug = models.SlugField(max_length=200)
ma = models.IntegerField(help_text="Indtast medarbejderens MA-nummer. (F.eks 123456)")
fornavn = models.CharField(max_length=30, help_text="Indtast medarbejderens fornavn.")
efternavn = models.CharField(max_length=30, help_text="Indtast medarbejderens efternavn.")
holdnavn = models.CharField(max_length=200, null=False, help_text="Indtast medarbejderens hold.")
delingnavn = models.ForeignKey('Deling', on_delete=models.CASCADE, null=True)
fagnavn = models.ForeignKey('Fag', on_delete=models.CASCADE, null=True)
The model is a model for employees (medarbejder). Now I wish to filter the teamname (holdnavn) with distinct, which I have accomplished. The next step is to then filter all the departments (delingnavn) within each teamname (holdnavn). So when I click on one teamname such as "GSU19", then I wish to get a list of all the departments within that teamname only.
I can't seem to wrap my head around how to do this? I am able to do it with slug and with pk, but both teamname and department are not a slug or a pk, so I'm abit lost to how to get the value in the url and filter again.
This is currently how the URL looks after I click on a specific teamname:
http://127.0.0.1:8000/hold/%3CQuerySet%20%5B%7B'delingnavn_id':%202%7D,%20%7B'delingnavn_id':%204%7D,%20%7B'delingnavn_id':%205%7D,%20%7B'delingnavn_id':%203%7D,%20%7B'delingnavn_id':%206%7D,%20%7B'delingnavn_id':%204%7D,%20%7B'delingnavn_id':%202%7D,%20%7B'delingnavn_id':%204%7D,%20%7B'delingnavn_id':%205%7D,%20%7B'delingnavn_id':%205%7D,%20%7B'delingnavn_id':%206%7D,%20%7B'delingnavn_id':%206%7D,%20%7B'delingnavn_id':%202%7D,%20%7B'delingnavn_id':%203%7D,%20%7B'delingnavn_id':%202%7D,%20%7B'delingnavn_id':%203%7D,%20%7B'delingnavn_id':%203%7D%5D%3E/
I'm getting all the department id's in the url..which is not what I want, I want them to be looped out in my template. Below is my current ListView:
class HoldDetailView(ListView):
model = Medarbejder
template_name = 'evalsys/medarbejder/list.html'
def get_context_data(self, **kwargs):
context = super(HoldDetailView, self).get_context_data(**kwargs)
context['medarbejder_hold'] = Medarbejder.objects.filter().values('holdnavn').distinct().order_by('holdnavn')
context['medarbejder_deling'] = Medarbejder.objects.filter().values('delingnavn_id').distinct()
return context
def get_object(self, holdnavn=None):
if holdnavn:
medarbejder_deling = Medarbejder.objects.filter().values('delingnavn_id').distinct()
else:
medarbejder_deling = self.medarbejder_deling
return render(self, 'evalsys/medarbejder/list.html',
{ 'medarbejder_deling': medarbejder_deling})
Please ask any questions and I'll supply more code, I think my approach is incorrect, but I can't seem to figure out how to go about it.
For clarification:
Delingnavn = DepartmentName and is a foreign key to Departments.
Holdnavn = TeamName
Fornavn = FirstName
Efternavn = LastName
FagNavn = SubjectName
I wish to get all the teamNames, click on one, and see all the departments within that team.
Update
In template:
{% for h in medarbejder_hold %}
<li>
{{ h.holdnavn }}
</li>
{% endfor %}
And I've done it like this because usually I use slug or pk...
URLs:
path('', views.HoldDetailView.as_view(), name='home'),
path('hold/<str:holdnavn>/', views.HoldDetailView.as_view(), name='get_object'),
This code is all over the place, unfortunately. get_object isn't ever called in a ListView, which is just as well; you can't render inside that method, it's for returning an object. And as I said, the URL itself is nonsense, you can't expect to just dump a queryset into a URL.
But it's not clear why you think you need to do either of these. If you want to filter by a specific holdnavn, then just pass that value into the URL and filter appropriately. (Note, I've changed the way you get the list of holdavn to make things a bit simpler.)
{% for holdnavn in medarbejder_hold %}
<li>
{{ holdnavn }}
</li>
{% endfor %}
class HoldListView(ListView):
model = Medarbejder
template_name = 'evalsys/medarbejder/list.html'
context_object_name = 'medarbejder_deling'
def get_context_data(self, **kwargs):
context = super(HoldDetailView, self).get_context_data(**kwargs)
context['medarbejder_hold'] = Medarbejder.objects.filter().values_list('holdnavn').distinct().order_by('holdnavn')
return context
def get_queryset(self):
qs = super().get_queryset()
if 'holdavn' in self.kwargs:
qs = qs.filter(holdavn=self.kwargs['holdavn'])
return qs

Django Form: Select Multipe allow to add the objects

I have a problem when I want to save the objects such as the Tags, and always returned an error because form validation.
Select a valid choice. hello is not one of the available choices.
Here, I want to implement the select input dynamically which customs additional value from the users creation.
For the frontend demo, like this snippet: https://jsfiddle.net/agaust/p377zxu4/
As conceptually, the tags input provide available tags that already created before... But, the important thing is the Users are allowed to create additional tags what they wants.
1. here is my models.py
#python_2_unicode_compatible
class Tag(models.Model):
title = models.CharField(max_length=200)
slug = models.SlugField(max_length=200, unique=True)
def __str__(self):
return self.title
class Meta:
verbose_name = _('Detail Tag')
verbose_name_plural = _('Tags')
#python_2_unicode_compatible
class Thread(TimeStampedModel):
title = models.CharField(max_length=200)
....
tags = models.ManyToManyField(
Tag, blank=True, related_name='tags_thread')
2. forms.py
from myapp.models import (Tag, Thread)
class ThreadForm(forms.ModelForm):
description = DraceditorFormField()
tags = forms.ModelMultipleChoiceField(
to_field_name='slug', # set the value to slug field, not pk/id
required=False,
label=_('Additional tags'),
help_text=_('Sparate by comma to add more than once, or select from available tags'),
queryset=Tag.objects.all(),
widget=forms.SelectMultiple(attrs={
'placeholder': _('Additional tags'),
'class': 'ui search fluid dropdown dropdown-add-tags'
})
)
class Meta:
model = Thread
fields = '__all__'
exclude = [
'author', 'topic', 'rating',
'created', 'modified'
]
widgets = {
'title': forms.TextInput(attrs={'placeholder': _('Title')})
}
def clean(self):
# this condition only if the POST data is cleaned, right?
cleaned_data = super(ThreadForm, self).clean()
print(cleaned_data.get('tags')) # return queryset of tags
3. views.py
def save_tagging(post_getlist_tags):
"""
return value list of slugs from the filed of `tags`.
allow to create if the tag is doesn't exist.
this function bassed on slug field.
:param `post_getlist_tags` is request.POST.getlist('tags', [])
"""
cleaned_slug_tags = []
for value in post_getlist_tags:
slug = slugify(value)
if Tag.objects.filter(slug=slug).exists():
cleaned_slug_tags.append(slug)
else:
tag = Tag.objects.create(title=value, slug=slug)
cleaned_slug_tags.append(tag.slug)
return cleaned_slug_tags
#login_required
def thread_new(request, topic_slug):
....
topic = get_object_or_404(Topic, slug=topic_slug)
if request.method == 'POST':
form = ThreadForm(request.POST, instance=Thread())
if form.is_valid():
initial = form.save(commit=False)
initial.author = request.user
initial.topic = topic
# set tagging, this will not being executed because error form validation
initial.tags = save_tagging(request.POST.getlist('tags', []))
initial.save()
form.save()
else:
# forms.errors # goes here..
Let checkout what I have when I typing the additional tags,
<select multiple="multiple" id="id_tags" name="tags" placeholder="Additional tags">
<option value="hello" class="addition">hello</option>
<option value="albacore-tuna" class="addition">albacore-tuna</option>
<option value="amur-leopard" class="addition">amur-leopard</option>
<option value="This other once" class="addition">This other once</option>
</select>
This why I implement my field of tags in the form is like this...
tags = forms.ModelMultipleChoiceField(
to_field_name='slug'
....
)
I would be very appreciated for the answers... :)
Update Solved
Thank you so much for #Resley Rodrigues for help.. Finally, I got it without the form field... only handled in the views and the template.
def save_tagging(post_getlist_tags):
"""
return objects list of tags.
allow to create if the tag is doesn't exist.
this function bassed on slug field.
:param `post_getlist_tags` is request.POST.getlist('fake_tags', [])
"""
cleaned_tags = []
for value in post_getlist_tags:
slug = slugify(value)
if Tag.objects.filter(slug=slug).exists():
tag = Tag.objects.filter(slug=slug).first()
cleaned_tags.append(tag)
else:
# makesure the slug is not empty string.
# because I found the empty string is saved.
if bool(slug.strip()):
tag = Tag.objects.create(title=value, slug=slug)
tag.save()
cleaned_tags.append(tag)
return cleaned_tags
#login_required
def thread_new(request, topic_slug):
....
if request.method == 'POST':
form = ThreadForm(request.POST, instance=Thread())
if form.is_valid():
initial = form.save(commit=False)
initial.author = request.user
....
form.save()
# set tagging after created the object
saved_tags = save_tagging(request.POST.getlist('fake_tags', []))
initial.tags.add(*saved_tags)
and the templates.html using field named by fake_tags, I just think it should hasn't crash with field that already named by tags.
<select name="fake_tags" multiple="multiple" class="ui search fluid dropdown dropdown-add-tags"></select>
<script>
$(document).ready(function() {
$('.ui.dropdown.dropdown-add-tags').dropdown({
placeholder: '{% trans "Additional tags" %}',
allowAdditions: true,
minCharacters: 3,
apiSettings: {
url: 'http://api.semantic-ui.com/tags/{query}'
}
});
});
</script>
For edit mode, add the following these lines below after end-tag of $('.ui.dropdown.dropdown-add-tags').dropdown({...});
thread is instance object.
var items = [{% for tag in thread.tags.all %}"{{ tag.title }}"{% if not forloop.last %},{% endif %}{% endfor %}];
$('.ui.dropdown.dropdown-add-tags').dropdown(
'set selected', items
);

Django: Populating ModelChoiceField

I have been searching up and down and I can't seem to find the right answer.
I have been playing around with django and with my test project and I can't figure out how to implement this, I am trying to display dropdown contents dynamically based on foreign key from my views
Here is my sample views:
def job_display(request):
job_list = Job_Posting.objects.filter(Publication_Status="A", Available_Slots__gt=0).order_by('-Urgency_Status', '-Date_Modified')
context = {'job_list': job_list}
return render(request, 'frontend/home.html', context)
def save_page(request, job_id):
jreq = get_object_or_404(Job_Posting, fkey=job_id)
form = application_form(request.POST)
if request.method == 'POST':
.....
else:
.....
return render(request, 'frontend/apply.html ... )
My urls:
urlpatterns = patterns('',
url(r'^$', views.job_display, name='job_display'),
url(r'^(?P<job_id>[0-9]+)/apply$', views.save_page, name='save_page'),
)
My froms:
class edbackgound(ModelForm):
COURSE = forms.ModelChoiceField(queryset=Educational_Requirement.objects.all())
my models:
class Course_Selection(models.Model):
Course = models.CharField(max_length=30, unique=True)
Abbreviation = models.CharField(max_length=100, unique=True)
class Job(models.Model):
Job_Position = models.CharField(max_length=30, null=True, unique=True)
class Job_Posting(models.Model):
fkey = models.OneToOneField(Job, verbose_name="Job Positions")
....
class Educational_Requirement(models.Model):
fkey = models.OneToOneField(Job_Posting, verbose_name="Job Positions")
Ed_req = models.OneToOneField(Course_Selection, verbose_name = 'Educational Requirement')
def __unicode__(self):
return self.Ed_req
My problem is displaying the choices in modelform, in my views I can get the currently selected job_list through save_page's jreq via jreq.fkey where I can just get it's Job_position then save my form. How can I populate my form's ModelChoiceField through my selected job_list.
If my post is not clear, please, feel free to comment what my post lacks
EDIT
I have found out that you can set your queryset via views like this:
form.fields['COURSE'].queryset = Educational_Requirement.objects.filter(fkey=jreq.fkey_id)
My problem with that is I am using an inlineformset_factory to generate my fields dynamically, and if I do this:
for form in myinlineform:
form.fields['COURSE'].queryset = Educational_Requirement.objects.filter(fkey=jreq.fkey_id)`
I am raising an error that says: [u'ManagementForm data is missing or has been tampered with']
Make sure you have included the management form for your inline formset in your template:
{{ my_formset.management_form }}
Read more on it here: https://docs.djangoproject.com/en/dev/topics/forms/formsets/#understanding-the-managementform

Categories

Resources