Creating a ModelForm with an arugment
I have some simple models of questions and answers.
#models.py
class Question(models.Model):
question_text = models.CharField(max_length=200)
question_info = models.TextField()
def __str__(self):
return self.question_text
class Answer(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
answer_text = models.CharField(max_length=200)
correct = models.BooleanField(default=False)
def __str__(self):
return self.answer_text
I am trying to create a ModelForm that takes all the answers for a given question and displays them with radio buttons. I can do this in views.py and the template just fine.
#views.py
def index(request):
q1 = Question.objects.get(pk=1)
context = {
'q1`': q1,
}
return render(request, 'questions/index.html', context)
\#index.html
<head>
<meta charset="utf-8" />
<title>Django</title>
</head>
<body>
<h1>Welcome!</h1>
<h2> {{ q_1.q_text }}</h2>
<form action="" method="POST">
{% csrf_token %}
{% for answer in q_1.answer_set.all %}
<input type="radio" name="answer" id="answer{{ forloop.counter }} value="{{ answer.id }}" />
<label for="choice{{ forloop.counter }}"> {{ answer.answer_text }} </label></br/>
{% endfor %}
<input type="submit" value="Submit" />
</form>
With this I can't call is_valid() so I tried to make a form for the model.
\#forms.py
class AnswerForm(forms.ModelForm):
class Meta:
model = Answer
a1 = Answer.objects.get(id=1)
a2 = Answer.objects.get(id=2)
a3 = Answer.objects.get(id=3)
a4 = Answer.objects.get(id=4)
a5 = Answer.objects.get(id=5)
fields = [
'correct',
]
widgets = {
'correct': forms.RadioSelect(choices = [
(a1.correct, Answer.objects.get(id=1)),
(a2.correct, Answer.objects.get(id=2)),
(a3.correct, Answer.objects.get(id=3)),
(a4.correct, Answer.objects.get(id=4)),
(a5.correct, Answer.objects.get(id=5))
]
)
}
This allows me to use the is_valid() method for validating the form but it is obviously inefficient as it only works for this one question. I would ideally like to the be able to pass a parameter into the ModelForm so that it uses that value to get the question whether from the id/pk or some other value. My thinking for this would then be that the ModelForm uses lets say id as its argument then I could also set up a url that takes the id of a question also and then when I pass the id in the view along with the request that id also gets used in the ModelForm. So I guess my questions are:
1. Is creating a ModelForm with an arugment for a specific object in the model possible?
2. Is the logic behind using the url id to pass to the ModelForm able to work as well?
Any help is appreciated, Thanks.
/r/djangolearning
http://redd.it/5adqqi
I have some simple models of questions and answers.
#models.py
class Question(models.Model):
question_text = models.CharField(max_length=200)
question_info = models.TextField()
def __str__(self):
return self.question_text
class Answer(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
answer_text = models.CharField(max_length=200)
correct = models.BooleanField(default=False)
def __str__(self):
return self.answer_text
I am trying to create a ModelForm that takes all the answers for a given question and displays them with radio buttons. I can do this in views.py and the template just fine.
#views.py
def index(request):
q1 = Question.objects.get(pk=1)
context = {
'q1`': q1,
}
return render(request, 'questions/index.html', context)
\#index.html
<head>
<meta charset="utf-8" />
<title>Django</title>
</head>
<body>
<h1>Welcome!</h1>
<h2> {{ q_1.q_text }}</h2>
<form action="" method="POST">
{% csrf_token %}
{% for answer in q_1.answer_set.all %}
<input type="radio" name="answer" id="answer{{ forloop.counter }} value="{{ answer.id }}" />
<label for="choice{{ forloop.counter }}"> {{ answer.answer_text }} </label></br/>
{% endfor %}
<input type="submit" value="Submit" />
</form>
With this I can't call is_valid() so I tried to make a form for the model.
\#forms.py
class AnswerForm(forms.ModelForm):
class Meta:
model = Answer
a1 = Answer.objects.get(id=1)
a2 = Answer.objects.get(id=2)
a3 = Answer.objects.get(id=3)
a4 = Answer.objects.get(id=4)
a5 = Answer.objects.get(id=5)
fields = [
'correct',
]
widgets = {
'correct': forms.RadioSelect(choices = [
(a1.correct, Answer.objects.get(id=1)),
(a2.correct, Answer.objects.get(id=2)),
(a3.correct, Answer.objects.get(id=3)),
(a4.correct, Answer.objects.get(id=4)),
(a5.correct, Answer.objects.get(id=5))
]
)
}
This allows me to use the is_valid() method for validating the form but it is obviously inefficient as it only works for this one question. I would ideally like to the be able to pass a parameter into the ModelForm so that it uses that value to get the question whether from the id/pk or some other value. My thinking for this would then be that the ModelForm uses lets say id as its argument then I could also set up a url that takes the id of a question also and then when I pass the id in the view along with the request that id also gets used in the ModelForm. So I guess my questions are:
1. Is creating a ModelForm with an arugment for a specific object in the model possible?
2. Is the logic behind using the url id to pass to the ModelForm able to work as well?
Any help is appreciated, Thanks.
/r/djangolearning
http://redd.it/5adqqi
Not understanding field__icontains?
I'm having a problem implementing a database query using a string.
I've tried many different methods with all of the same results, and am nowhere closer to the goal.
#urls.py
url(r'^api/v1/item/nomen/contains/(?P<nomen>[\w\-]+)/$', views.ItemListContainsNomen.as_view(), name='item_lookup_contains_nomen'),
#views.py
class ItemListContainsNomen(generics.ListAPIView):
serializer_class = ItemSerializer
def get_queryset(self):
nomen = self.kwargs['nomen']
return Item.objects.filter(nomenclature__icontains=nomen)
class Item(models.Model):
id = models.IntegerField(primary_key=True)
nomenclature = models.CharField(max_length=35)
This nets me a warning such as
> "/.virtualenvs/realDjango/local/lib/python2.7/site-packages/django/db/backends/mysql/base.py:110: Warning: Truncated incorrect DOUBLE value: 'nomen/contains/CLOSER'
>
> return self.cursor.execute(query, args)
>
> Not Found: /api/v1/item/nomen/contains/CLOSER/"
I can successfully run this query using the MYSQL console and raw MYSQL with LIKE, and I can successfully query another database's TextField using the same syntax in Django.....but this column just doesn't seem to work no matter what. There has to be something I'm missing. I should also note, replacing icontains=nomen with say, icontains="CLOSER" also yields the same errors.
Checking datatype in console shows
> +-----------+
> | DATA_TYPE |
> +-----------+
> | varchar |
> +-----------+
> 1 row in set (1.39 sec)
/r/django
https://redd.it/6a0tz9
I'm having a problem implementing a database query using a string.
I've tried many different methods with all of the same results, and am nowhere closer to the goal.
#urls.py
url(r'^api/v1/item/nomen/contains/(?P<nomen>[\w\-]+)/$', views.ItemListContainsNomen.as_view(), name='item_lookup_contains_nomen'),
#views.py
class ItemListContainsNomen(generics.ListAPIView):
serializer_class = ItemSerializer
def get_queryset(self):
nomen = self.kwargs['nomen']
return Item.objects.filter(nomenclature__icontains=nomen)
class Item(models.Model):
id = models.IntegerField(primary_key=True)
nomenclature = models.CharField(max_length=35)
This nets me a warning such as
> "/.virtualenvs/realDjango/local/lib/python2.7/site-packages/django/db/backends/mysql/base.py:110: Warning: Truncated incorrect DOUBLE value: 'nomen/contains/CLOSER'
>
> return self.cursor.execute(query, args)
>
> Not Found: /api/v1/item/nomen/contains/CLOSER/"
I can successfully run this query using the MYSQL console and raw MYSQL with LIKE, and I can successfully query another database's TextField using the same syntax in Django.....but this column just doesn't seem to work no matter what. There has to be something I'm missing. I should also note, replacing icontains=nomen with say, icontains="CLOSER" also yields the same errors.
Checking datatype in console shows
> +-----------+
> | DATA_TYPE |
> +-----------+
> | varchar |
> +-----------+
> 1 row in set (1.39 sec)
/r/django
https://redd.it/6a0tz9
reddit
Not understanding field__icontains? • r/django
I'm having a problem implementing a database query using a string. I've tried many different methods with all of the same results, and am nowhere...
[HELP] My details page isn't shown, why?
Hi, people. I'm a beginner Django developer so sorry if it's a basic question.
I have a webpage that shows a list of movies and each movie has a details view, but for some reason, the details view is never rendered.
#views.py
def index(request):
latest_movies = Movie.objects.order_by('-movie_id')[:5]
template = loader.get_template('ytsmirror/index.html')
context = {
'latest_movies' : latest_movies,
}
return HttpResponse(template.render(context, request))
def detail(request, movie_id):
movie = Movie.objects.get(movie_id=movie_id)
template = loader.get_template('ytsmirror/details.html')
context = {
'movie' : movie,
'plot': 'Lorem impsum',
}
return HttpResponse(template.render(context, request))
And my urls.py
#urls.py
from django.conf.urls import url
from . import views
app_name = 'ytsmirror'
urlpatterns = [
url(r'$', views.index, name='index'),
url(r'^(?P<movie_id>\d{4})$', views.detail, name='detail'),
]
When I try to reach /ytsmirror/4200/ for example, I don't get any error and Django apparently reaches the correct URL pattern but doesn't render the details view, it stays on the index view, without any change.
What am I doing wrong?
/r/djangolearning
https://redd.it/6lhjxy
Hi, people. I'm a beginner Django developer so sorry if it's a basic question.
I have a webpage that shows a list of movies and each movie has a details view, but for some reason, the details view is never rendered.
#views.py
def index(request):
latest_movies = Movie.objects.order_by('-movie_id')[:5]
template = loader.get_template('ytsmirror/index.html')
context = {
'latest_movies' : latest_movies,
}
return HttpResponse(template.render(context, request))
def detail(request, movie_id):
movie = Movie.objects.get(movie_id=movie_id)
template = loader.get_template('ytsmirror/details.html')
context = {
'movie' : movie,
'plot': 'Lorem impsum',
}
return HttpResponse(template.render(context, request))
And my urls.py
#urls.py
from django.conf.urls import url
from . import views
app_name = 'ytsmirror'
urlpatterns = [
url(r'$', views.index, name='index'),
url(r'^(?P<movie_id>\d{4})$', views.detail, name='detail'),
]
When I try to reach /ytsmirror/4200/ for example, I don't get any error and Django apparently reaches the correct URL pattern but doesn't render the details view, it stays on the index view, without any change.
What am I doing wrong?
/r/djangolearning
https://redd.it/6lhjxy
reddit
[HELP] My details page isn't shown, why? • r/djangolearning
Hi, people. I'm a beginner Django developer so sorry if it's a basic question. I have a webpage that shows a list of movies and each movie has a...
How to render form fields conditionally in django
I have two user groups.
1. Writer
2. editors
If the user is logged in as a writer, display the `title` and `body` field of an Article model, if the user is logged in as an Editor, display `title` `body` and `approved` field so the Editor can approve the article by review it.
I need to implement this feature without using Django admin. how could I achieve this?
class Article(models.Model):
choices = (("review", "Review"))
title = models.CharField("Article title", max_length=200)
body = models.TextField()
writer = models.ForeignKey(User, on_delete=models.CASCADE)
status = models.CharField(
max_length=20,
choices=(
('reivew', 'review'),
('published', 'published')
)
)
def get_absolute_url(self):
reverse('article-detail', kwargs={
"pk": self.id
})
#views.py
class ArticleCreate(CreateView):
model = Article
# Don't need to define inside meta class
fields = ("title", "body")
# Override the form_valid method to populate your data.
def form_valid(self, form):
form.instance.writer = self.request.user
form.instance.status = "published"
return super(ArticleCreate, self).form_valid(form)
# Don't need success url
# get_absolute_url is already defined in model
Q. Where to write a logic to hide and display the `status` field based on user group type
if u.groups.filter(name="Editors").exists():
#display status field
else:
# hide status field.
I know I could do thisn using django admin, using this logic, but I want to implement using my own generic views and forms.
class ArticleAdmin(admin.ModelAdmin):
fields = ['title', 'body'] # here comes the fields open to all users
def change_view(self, request, object_id, extra_context=None): # override default admin change behaviour
if request.user in Editors: # an example
self.fields.append('status') # add field 2 to your `fields`
/r/django
https://redd.it/7hee2d
I have two user groups.
1. Writer
2. editors
If the user is logged in as a writer, display the `title` and `body` field of an Article model, if the user is logged in as an Editor, display `title` `body` and `approved` field so the Editor can approve the article by review it.
I need to implement this feature without using Django admin. how could I achieve this?
class Article(models.Model):
choices = (("review", "Review"))
title = models.CharField("Article title", max_length=200)
body = models.TextField()
writer = models.ForeignKey(User, on_delete=models.CASCADE)
status = models.CharField(
max_length=20,
choices=(
('reivew', 'review'),
('published', 'published')
)
)
def get_absolute_url(self):
reverse('article-detail', kwargs={
"pk": self.id
})
#views.py
class ArticleCreate(CreateView):
model = Article
# Don't need to define inside meta class
fields = ("title", "body")
# Override the form_valid method to populate your data.
def form_valid(self, form):
form.instance.writer = self.request.user
form.instance.status = "published"
return super(ArticleCreate, self).form_valid(form)
# Don't need success url
# get_absolute_url is already defined in model
Q. Where to write a logic to hide and display the `status` field based on user group type
if u.groups.filter(name="Editors").exists():
#display status field
else:
# hide status field.
I know I could do thisn using django admin, using this logic, but I want to implement using my own generic views and forms.
class ArticleAdmin(admin.ModelAdmin):
fields = ['title', 'body'] # here comes the fields open to all users
def change_view(self, request, object_id, extra_context=None): # override default admin change behaviour
if request.user in Editors: # an example
self.fields.append('status') # add field 2 to your `fields`
/r/django
https://redd.it/7hee2d
reddit
How to render form fields conditionally in django • r/django
I have two user groups. 1. Writer 2. editors If the user is logged in as a writer, display the `title` and `body` field of an Article model, if...
Formatting and tweaking inline formsets
Hey everyone,
I was wondering if anyone had any good ideas on how to format and tweak inline formsets, especially instances when a parent model has multiple, complex children.
As it stands, I can only get inlines to pass through as context by using `inlineformset_factory` in my forms and then passing that formset through in my `get_context_data` as such:
#forms.py
from django.forms.models import inlineformset_factory
LitigantFormset = inlineformset_factory(models.Case, models.Litigant, fields=('person', 'role', 'fine'))
---
#views.py
class CaseEditView(GroupRequiredMixin, UpdateView):
model = models.Case
fields = ['session', 'case_type', 'court_type', 'verdict', 'of_interest', 'ad_legem',
'villeinage_mention', 'active_sale', 'incidental_land', 'summary',]
template_name = 'case/case_edit.html'
group_required = Edit
def get_context_data(self, **kwargs):
context = super(CaseEditView, self).get_context_data(**kwargs)
if self.request.POST:
context['formset'] = forms.LitigantFormset(self.request.POST, instance=self.object)
else:
context['formset'] = forms.LitigantFormset(instance=self.object)
return context
def get_success_url(self):
pk = self.kwargs.get('pk')
return reverse('case', kwargs={'pk': pk})
---
However, when I instantiate the formset in my html template it is ass-ugly, to put it lightly.
I am using [django-widget-tweaks](https://pypi.python.org/pypi/django-widget-tweaks) to modify the template code for my normal forms, but when I try to do any modifications to the formset the debugger informs me that `'LitigantForm' object has no attribute 'form'`. This obviously makes sense, because `LitigantForm` is a context, not a form.
Does anyone have any tricks for formatting inline formsets and working with them in an easy and DRY way?
I would especially like to be able to dynamically add and delete both whole instances, but also add and delete fields within the inline instances themselves (e.g. add a fine to a person or remove it; only having the 'fine' field show when I click an 'add fine' button). This would obviously be js/jquery, but without the ability to individually manipulate the form fields of the inlines, I just don't see how it's possible.
I would really appreciate any pointers or advice! Thanks!
/r/django
https://redd.it/7s8wiw
Hey everyone,
I was wondering if anyone had any good ideas on how to format and tweak inline formsets, especially instances when a parent model has multiple, complex children.
As it stands, I can only get inlines to pass through as context by using `inlineformset_factory` in my forms and then passing that formset through in my `get_context_data` as such:
#forms.py
from django.forms.models import inlineformset_factory
LitigantFormset = inlineformset_factory(models.Case, models.Litigant, fields=('person', 'role', 'fine'))
---
#views.py
class CaseEditView(GroupRequiredMixin, UpdateView):
model = models.Case
fields = ['session', 'case_type', 'court_type', 'verdict', 'of_interest', 'ad_legem',
'villeinage_mention', 'active_sale', 'incidental_land', 'summary',]
template_name = 'case/case_edit.html'
group_required = Edit
def get_context_data(self, **kwargs):
context = super(CaseEditView, self).get_context_data(**kwargs)
if self.request.POST:
context['formset'] = forms.LitigantFormset(self.request.POST, instance=self.object)
else:
context['formset'] = forms.LitigantFormset(instance=self.object)
return context
def get_success_url(self):
pk = self.kwargs.get('pk')
return reverse('case', kwargs={'pk': pk})
---
However, when I instantiate the formset in my html template it is ass-ugly, to put it lightly.
I am using [django-widget-tweaks](https://pypi.python.org/pypi/django-widget-tweaks) to modify the template code for my normal forms, but when I try to do any modifications to the formset the debugger informs me that `'LitigantForm' object has no attribute 'form'`. This obviously makes sense, because `LitigantForm` is a context, not a form.
Does anyone have any tricks for formatting inline formsets and working with them in an easy and DRY way?
I would especially like to be able to dynamically add and delete both whole instances, but also add and delete fields within the inline instances themselves (e.g. add a fine to a person or remove it; only having the 'fine' field show when I click an 'add fine' button). This would obviously be js/jquery, but without the ability to individually manipulate the form fields of the inlines, I just don't see how it's possible.
I would really appreciate any pointers or advice! Thanks!
/r/django
https://redd.it/7s8wiw
pypi.python.org
django-widget-tweaks 1.4.2 : Python Package Index
Tweak the form field rendering in templates, not in python-level form definitions.
how to redirect to a different page when a error occurs?
i want to redirect to the jobseekerprofileUpdateView if value error occurs in jobseekerprofileDetailView. error goes away when user update their profile
can you guys help me with a solution.
error is:
ValueError at /employer/profile/view
The 'company\_logo' attribute has no file associated with it.
#views
class jobseekerprofileUpdateView(LoginRequiredMixin,jobseekerMixin,UpdateView):
model= jobseekerprofile
fields = \['profile\_photo','first\_name','last\_name','contact\_email','residence','about','education','experience','skills'\]
template\_name = "jobseeker/update\_profile.html"
success\_url =reverse\_lazy('home')
def get\_object(self):
obj= self.request.user.jobseekerprofile
return obj
class jobseekerprofileDetailView(LoginRequiredMixin,jobseekerMixin,DetailView):
model = jobseekerprofile
template\_name = 'jobseeker/profile.html'
def get\_object(self):
obj= self.request.user.jobseekerprofile
return obj
sorry for my shit english
/r/django
https://redd.it/c2tovs
i want to redirect to the jobseekerprofileUpdateView if value error occurs in jobseekerprofileDetailView. error goes away when user update their profile
can you guys help me with a solution.
error is:
ValueError at /employer/profile/view
The 'company\_logo' attribute has no file associated with it.
#views
class jobseekerprofileUpdateView(LoginRequiredMixin,jobseekerMixin,UpdateView):
model= jobseekerprofile
fields = \['profile\_photo','first\_name','last\_name','contact\_email','residence','about','education','experience','skills'\]
template\_name = "jobseeker/update\_profile.html"
success\_url =reverse\_lazy('home')
def get\_object(self):
obj= self.request.user.jobseekerprofile
return obj
class jobseekerprofileDetailView(LoginRequiredMixin,jobseekerMixin,DetailView):
model = jobseekerprofile
template\_name = 'jobseeker/profile.html'
def get\_object(self):
obj= self.request.user.jobseekerprofile
return obj
sorry for my shit english
/r/django
https://redd.it/c2tovs
reddit
r/django - how to redirect to a different page when a error occurs?
4 votes and 2 comments so far on Reddit
i want to Redirect to the same view after delete??
**so after deleting comment i can't back to detailviews of my comments , i need back with the pk of the post**
\#error
`Reverse for 'CommentsBack' not found. 'CommentsBack' is not a valid view function or pattern`
#views
# list all the comments of ever post l
class comment_back (DetailView):
model=Post
template_name='CommentsBack.html'
#delete comment by his primary key
def delete_comment(self,pk):
event=Comment.objects.get(pk=pk)
event.delete()
return redirect('CommentBack')
​
#urls
path('mypost/<int:pk>/commentBack', comment_back.as_view(),name="commentBack"),
path('DeleteComment/<int:pk>/remove', views.delete_comment,name="delete_comment"),
/r/djangolearning
https://redd.it/uplkto
**so after deleting comment i can't back to detailviews of my comments , i need back with the pk of the post**
\#error
`Reverse for 'CommentsBack' not found. 'CommentsBack' is not a valid view function or pattern`
#views
# list all the comments of ever post l
class comment_back (DetailView):
model=Post
template_name='CommentsBack.html'
#delete comment by his primary key
def delete_comment(self,pk):
event=Comment.objects.get(pk=pk)
event.delete()
return redirect('CommentBack')
​
#urls
path('mypost/<int:pk>/commentBack', comment_back.as_view(),name="commentBack"),
path('DeleteComment/<int:pk>/remove', views.delete_comment,name="delete_comment"),
/r/djangolearning
https://redd.it/uplkto
reddit
i want to Redirect to the same view after delete??
**so after deleting comment i can't back to detailviews of my comments , i need back with the pk of the post** \#error `Reverse for...
How do I add a new entry to my many to many related table in Django?
I have two models Course and Educators. Course has 3 fields course\_name, course\_educators and course\_past\_educators which link Educators to Courses by many to many. I want to write a function so that whenever a new entry is added to course\_educators that entry will be copied over to course\_past\_educators.
#models.py
#code for Educators model
class Educators(models.Model):
educator_name=models.CharField(max_length=20,default=None)
educator_img = models.ImageField(upload_to='educators_img',default=None)
#code for Courses model
class Course(models.Model):
course_name = models.CharField(max_length=100)
course_educators=models.ManyToManyField(Educators, related_name='current_educators', default=None, blank=True)
course_past_educators=models.ManyToManyField(Educators, related_name='past_educators', default=None, blank=True)
#views.py
#This is the function I wrote so that entries into course_past_educators are automatically added when course_educators is added with another entry.
u/receiver(m2m_changed, sender=Course.course_educators.through)
def create_past_educator_on_add(sender, instance, action, reverse, model, pk_set, **kwargs):
if action == 'post_add' and reverse is False:
/r/djangolearning
https://redd.it/1cq2j42
I have two models Course and Educators. Course has 3 fields course\_name, course\_educators and course\_past\_educators which link Educators to Courses by many to many. I want to write a function so that whenever a new entry is added to course\_educators that entry will be copied over to course\_past\_educators.
#models.py
#code for Educators model
class Educators(models.Model):
educator_name=models.CharField(max_length=20,default=None)
educator_img = models.ImageField(upload_to='educators_img',default=None)
#code for Courses model
class Course(models.Model):
course_name = models.CharField(max_length=100)
course_educators=models.ManyToManyField(Educators, related_name='current_educators', default=None, blank=True)
course_past_educators=models.ManyToManyField(Educators, related_name='past_educators', default=None, blank=True)
#views.py
#This is the function I wrote so that entries into course_past_educators are automatically added when course_educators is added with another entry.
u/receiver(m2m_changed, sender=Course.course_educators.through)
def create_past_educator_on_add(sender, instance, action, reverse, model, pk_set, **kwargs):
if action == 'post_add' and reverse is False:
/r/djangolearning
https://redd.it/1cq2j42
Reddit
From the djangolearning community on Reddit
Explore this post and more from the djangolearning community