I have a new problem, it is when I insert in the database the news, it adds but without the region. How can I insert the comment with the correct region?
Here is my view :
def index_region(request,region):
try:
actuCommentaire = Actu.objects.get(region=region)
except ObjectDoesNotExist:
actuTempo = Actu(region=region)
actuCommentaire = actuTempo.commentaire
form = UpdateActu(request.POST or None, instance=actuCommentaire)
if form.is_valid():
form.save()
return redirect('index.html')
Here is my model "Actu" :
class Actu(models.Model):
commentaire = models.TextField(max_length=200, null=True)
region = models.CharField(max_length=30, null=True)
def __str__(self):
return self.region
Here is my form :
class UpdateActu(forms.ModelForm):
class Meta:
model = models.Actu
fields = ['commentaire']
widgets = {
'commentaire': forms.Textarea(attrs={'class': 'form-control', 'id': 'exampleTextarea', 'rows': '2'})
}
Here is the result when inserting into the database :
enter image description here
I found how to solve the problem.
Here is my new view :
try:
actuCommentaire = Actu.objects.get(region=region)
except ObjectDoesNotExist:
actuTempo = Actu(region=region)
actuCommentaire = actuTempo.commentaire
form = UpdateActu(request.POST or None, instance=actuCommentaire)
if form.is_valid():
if Actu.objects.filter(region=region).count() == 0:
formActu = Actu(commentaire=request.POST['commentaire'], region=region)
formActu.save()
else:
form.save()
return redirect('index.html')
Related
I am currently making a flashcard web application with Django.
There is a 'set' page (dashboard) and a 'card' page (set-edit). When I fill in and submit the form on the card page (set-edit) to add a new card to the set which has been selected for editing, I received a value error ' Cannot assign "2": "Card.set" must be a "Set" instance.'
I'm unsure why this is happening because there is an instance of Set with an id of 2.
Any suggestions of how to rectify this issue?
views.py
###################
##Dashboard views##
###################
def dashboard(request):
set = Set.objects.all()
set_count = set.count()
if request.method == 'POST':
form = SetForm(request.POST)
if form.is_valid():
form.save()
set_name = form.cleaned_data.get('name')
messages.success(request, f'{set_name} has been added')
return redirect('dashboard-dashboard')
else:
form = SetForm()
context = {
'set': set,
'form': form,
}
return render(request, 'dashboard/dashboard.html', context)
#############
##Set views##
#############
#Cards is for when you are adding cards to a set or looking at the content of a set
def set_edit(request, pk):
set_title = Set.objects.get(id=pk)
card = Set.objects.get(id=pk).card_set.all()
set_id = pk
set = Set.objects.get(id=pk)
if request.method == 'POST':
form = CardForm(request.POST)
print('Entered Post condition')
if form.is_valid():
obj = form.save(commit=False)
obj.set = pk
obj.save()
card_name = form.cleaned_data.get('kanji')
messages.success(request, f'{card_name} has been added')
return redirect('dashboard-set-edit',pk)
else:
form = CardForm()
context = {
'card': card,
'form': form,
}
return render(request, 'dashboard/set_edit.html', context)
```
**models.py**
```
class Set(models.Model):
name = models.CharField(max_length=100, null=True)
quantity = models.PositiveIntegerField(null=True, blank=True)
date_created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f'{self.id}'
class Card(models.Model):
kanji = models.CharField(max_length=100, null=True)
kana = models.CharField(max_length=100, null=True)
english = models.CharField(max_length=100, null=True)
set = models.ForeignKey(Set, on_delete=models.CASCADE,default=3)
def __str__(self):
return f'{self.id}'
```
**forms.py**
```
class CardForm(forms.ModelForm):
class Meta:
model = Card
# fields = '__all__'
exclude = ('set',)
class SetForm(forms.ModelForm):
class Meta:
model = Set
fields = '__all__'
```
**urls.py**
urlpatterns = [
#########
##Sets###
#########
path('sets/edit/<int:pk>/', views.set_edit,
name='dashboard-set-edit'),
path('sets/delete/<int:pk>/', views.set_delete,
name='dashboard-set-delete'),
#########
##Cards##
#########
path('card/delete/<int:pk>/', views.card_delete,
name='dashboard-cards-delete'),
path('cards/detail/<int:pk>/', views.card_detail,
name='dashboard-cards-detail'),
path('cards/edit/<int:pk>/', views.card_edit,
name='dashboard-cards-edit'),
#############
##Dashboard##
#############
path('dashboard/', views.dashboard, name='dashboard-dashboard'),
]
```
You should assign it to .set_id, not .set:
if form.is_valid():
# use set_id ↓
form.instance.set_id = pk
obj = form.save()
card_name = form.cleaned_data.get('kanji')
messages.success(request, f'{card_name} has been added')
return redirect('dashboard-set-edit',pk)
Please Help!
I am trying to update a group of formsets that are related the main form (Project Information) by the main forms pk. The create form works fine, but I am finding it extremely difficult to implement the update version.
It's the save as an update part that I can't figure out for the formsets. The main form updates the database correctly. The formsets just create new records instead of updating the existing ones. I do not know how to instance the formsets.
Here the code.
view.py
#login_required
def edit_project(request):
SampleInformationFormSet = formset_factory(SampleInformationForm, extra=1)
DissolutionMethodsFormSet = formset_factory(DissolutionMethodsForm, extra=1)
form = ProjectInformationForm(request.POST or None)
si_formset = SampleInformationFormSet(request.POST or None, prefix='si')
d_formset = DissolutionMethodsFormSet(request.POST or None, prefix='d')
if request.method == 'POST':
form = ProjectInformationForm(request.POST or None)
si_formset = SampleInformationFormSet(request.POST or None, prefix='si')
d_formset = DissolutionMethodsFormSet(request.POST or None, prefix='d')
pi_pk = ''
p = ''
if form.is_valid():
pi_pk = form.cleaned_data['hd']
p = ProjectInformation.objects.get(pk=pi_pk)
form = ProjectInformationForm(request.POST, instance=p)
form.save() # This form saves correctly
for si_form in si_formset:
si_form.save() # I do not know how to attach an instance to these formsets
for d_form in d_formset:
d_form.save()
messages.success(request, 'Your project has been updated!')
return redirect('edit_project')
else:
pass
form = ProjectInformationForm(request.POST or None)
si_formset = SampleInformationFormSet(request.POST or None, prefix='si')
messages.warning(request, 'There was an error saving your form.')
study_id_select = list(
ProjectInformation.objects.values('dissolution_study_id', 'id').filter())
context = {'form': form, 'si_formset': si_formset, 'd_formset': d_formset, 'study_id_select': study_id_select}
return render(request, 'main/edit_project.html', context)
models.py I'm just going to include part of three of the seven models to keep this a little shorter.
class ProjectInformation(models.Model):
username = models.ForeignKey(User, on_delete=models.CASCADE)
compound_code = models.CharField(max_length=60)
product_type = models.ForeignKey(ProductType, on_delete=models.CASCADE)
main_component = models.CharField(max_length=100)
class SampleInformation(models.Model):
sample_index = models.CharField(max_length=30)
sample_type_purpose = models.ForeignKey(SampleTypePurpose, on_delete=models.CASCADE)
specification_number = models.CharField(max_length=20, blank=True, null=True)
project = models.ForeignKey(ProjectInformation, on_delete=models.CASCADE, blank=True, null=True)
class DissolutionMethods(models.Model):
number_of_methods = models.IntegerField(default=1,
validators=[MaxValueValidator(10), MinValueValidator(1)],
blank=True, null=True)
dissolution_method_index = models.CharField(max_length=10)
project = models.ForeignKey(ProjectInformation, on_delete=models.CASCADE, blank=True, null=True)
forms.py
class ProjectInformationForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['hd'] = forms.CharField(widget=forms.HiddenInput, required=False)
class Meta:
model = ProjectInformation
fields = '__all__'
class SampleInformationForm(forms.ModelForm):
class Meta:
model = SampleInformation
fields = '__all__'
Please help if you can. This project has been a trial by fire and the flames are hot!
Finally solved it myself.
#login_required
def edit_project(request):
SampleInformationFormSet = formset_factory(SampleInformationForm, extra=1)
DissolutionMethodsFormSet = formset_factory(DissolutionMethodsForm, extra=1)
form = ProjectInformationForm(request.POST or None)
si_formset = SampleInformationFormSet(request.POST or None, prefix='si')
d_formset = DissolutionMethodsFormSet(request.POST or None, prefix='d')
if request.method == 'POST':
form = ProjectInformationForm(request.POST or None)
si_formset = SampleInformationFormSet(request.POST or None, prefix='si')
d_formset = DissolutionMethodsFormSet(request.POST or None, prefix='d')
pi_pk = ''
p = ''
if form.is_valid():
pi_pk = form.cleaned_data['hd']
p = ProjectInformation.objects.get(pk=pi_pk)
form = ProjectInformationForm(request.POST, instance=p)
form.save()
si = p.sampleinformation_set.all() # All the Methods related to the instance
d = p.dissolutionmethods_set.all()
si_cnt = 0
for si_form in si_formset:
if si_form.is_valid():
update = si_form.save(commit=False)
update.pk = si[si_cnt].pk
update.save()
si_cnt += 1
d_cnt = 0
for d_form in d_formset:
if d_form.is_valid():
update = d_form.save(commit=False)
update.pk = d[d_cnt].pk
update.save()
d_cnt += 1
to count about multiply model with another model in foreignkey but in different app, here the penjualan app and detail_penjualan_obat model :
class detail_penjualan_obat(models.Model):
kd_penjualan_detail = models.ForeignKey(penjualan_obat)
kd_obat_detail = models.ForeignKey(obat)
jumlah_jual = models.IntegerField()
total_harga_perobat = MoneyField(max_digits=10, decimal_places=2, default_currency='IDR')
def __unicode__(self):
return self.total_harga_perobat
and the obat app model :
class obat(models.Model):
jenis_obat = {
('obat bebas','Obat Bebas'),
('obat bebas terbatas','Obat Bebas Terbatas'),
('obat keras dan psikotropika','Obat Keras dan Psikotropika')
}
kd_obat = models.CharField(primary_key = True, default = '', max_length = 10, validators=[RegexValidator(r'^\d{1,10}$')])
nama_obat = models.CharField(max_length = 15)
tipe_obat = models.CharField(max_length = 35, choices = jenis_obat)
harga_jual = MoneyField(max_digits=10, decimal_places=2, default_currency='IDR')
def __unicode__(self):
return self.kd_obat
and the view.py :
def data_penjualan_obat_detail(request):
if request.method == 'POST':
form_data = request.POST
form = penjualan_detail_form(form_data)
if form.is_valid():
input_detail_penjualan = detail_penjualan_obat(
kd_penjualan_detail = form.cleaned_data.get('kd_penjualan_detail'),
kd_obat_detail = form.cleaned_data.get('kd_obat_detail'),
jumlah_jual = request.POST['jumlah_jual'],
total_harga_perobat = form.cleaned_data.get('total_harga_perobat')
)
input_detail_penjualan.save()
return redirect('/')
else:
form = penjualan_detail_form()
return render(request, 'penjualan_detail.html',{'form':form})
here the function :
total_harga_perobat = harga_jual * jumlah_jual
and that function how to be 'place and work' in the view ?
Sorry I have bad english but I hope you will understand what about my question, and solve my problem
EDIT :
here model of penjualan_obat :
class penjualan_obat(models.Model):
kd_penjualan = models.CharField(primary_key = True, default = '', max_length = 10, validators=[RegexValidator(r'^\d{1,10}$')], unique = True)
kd_costumer_obat = models.ForeignKey(costumer)
tgl_penjualan = models.DateField(auto_now_add = True)
total_penjualan = MoneyField(max_digits=10, decimal_places=2, default_currency='IDR')
def __unicode__(self):
return self.kd_penjualan
and the form penjualan_detail_form :
class penjualan_detail_form(ModelForm):
class Meta:
model = detail_penjualan_obat
fields = ['kd_penjualan_detail','kd_obat_detail','jumlah_jual']
labels = {
'kd_penjualan_detail' : 'Kode Penjualan',
'kd_obat_detail' : 'Kode Obat',
'jumlah_penjualan' : 'Jumlah Penjualan',
}
error_messages = {
'kd_penjualan_detail':{
'required':'Anda harus memilih kode penjualan'
},
'kd_obat_detail':{
'required':'Anda harus memilih kode obat'
},
'jumlah_penjualan':{
'required':'Anda harus mengisi jumlah penjualan'
},
}
CORRECTIONS
I suggest you to change model class name with standard naming.
an example class detail_penjualan_obat(models.Model) to class DetailPenjualanObat(models.Model)
and I suggest you to not using default = '' to your unique field.
This will be difficult whenever you migrating the databases.
Why you implement to the form form.cleaned_data.get('total_harga_perobat'),
if you actually want to save it with automatically? you should handle it at your backend.
I checked at your source code, and your penjualan_detail_form
already instanced to the model of detail_penjualan_obat. perhaps like this below;
def data_penjualan_obat_detail(request):
if request.method == 'POST':
form = penjualan_detail_form(request.POST)
if form.is_valid():
initial = form.save(commit=False)
initial.total_harga_perobat = initial.kd_obat_detail.harga_jual * initial.jumlah_jual
initial.save()
form.save()
return redirect('/')
else:
form = penjualan_detail_form()
return render(request, 'penjualan_detail.html', {'form': form})
Hope it can help..
UPDATE
You also can handle it in your models.py, an example:
class DetailPenjualanObat(models.Model):
kd_penjualan_detail = models.ForeignKey(penjualan_obat)
kd_obat_detail = models.ForeignKey(obat)
jumlah_jual = models.IntegerField()
total_harga_perobat = MoneyField(max_digits=10, decimal_places=2, default_currency='IDR')
def save(self, *args, **kwargs):
self.total_harga_perobat = self.kd_obat_detail.harga_jual * self.jumlah_jual
super(DetailPenjualanObat, self).save(*args, **kwargs)
See also about pre save, like this answer
I have a form in my application which has a hidden form field, the value of which I want to set in my corresponding view after submitting the form.
forms.py
class EvangelizedForm(forms.ModelForm):
first_name = forms.CharField(help_text="First Name")
last_name = forms.CharField(help_text="Last Name")
email = forms.CharField(help_text="Email ID")
mobile_no = forms.CharField(help_text="Mobile number")
twitter_url = forms.CharField(help_text="Twitter URL")
twitter_followers = forms.CharField(widget = forms.HiddenInput()) #Hidden form field
class Meta:
model = Evangelized
fields = ('first_name','last_name', 'twitter_url', 'email', 'mobile_no')
models.py
class Evangelized(models.Model):
first_name = models.CharField(max_length=128)
last_name = models.CharField(max_length=128)
email = models.EmailField()
mobile_no = models.CharField(unique=True, max_length = 10, validators=[RegexValidator(regex='^\w{10}$', message='Mobile number should be strictly of 10 digits.')])
twitter_url = models.CharField(unique=True, max_length=128)
twitter_followers = models.CharField(max_length = 128)
views.py
def fillform(request):
follower_count = '250'
if request.method == 'POST':
form = EvangelizedForm(request.POST)
if form.is_valid():
form.fields['twitter_followers'] = follower_count
form.save(commit=True)
return index(request)
else:
form.errors
else:
#form = EvangelizedForm()
if request.user.is_authenticated():
form = EvangelizedForm(initial={'first_name': request.user.first_name,
'twitter_url': 'https://twitter.com/' + request.user.username,
'last_name': request.user.last_name})
else:
form = EvangelizedForm()
context = RequestContext(request,
{'request': request,
'user': request.user, 'form':form})
#return render(request, 'rango/fillform.html', {'form': form, 'context_instance':context})
return render_to_response('rango/fillform.html',
context_instance=context)
Basically, I'm trying to set the value of twitter_followers (which is a hidden form field in forms.py) in my index view, by:
follower_count = '250'
..
..
form.fields['twitter_followers'] = follower_count
By doing this, I'm expecting the value of 'twitter_followers' in the database after submitting the form to be '250'. However, this approach doesn't seem to be working.
What's the right way to set values to certain attributes in the database manually using views?
You need to set it on the model instance, which is the result of form.save. That's the main reason for the commit argument in the first place.
if form.is_valid()
obj = form.save(commit=True)
obj.twitter_follower = follower_count
obj.save()
You can override the save method of the form, with something like this:
def save(self, *args, **kwargs)
twitter_followers = kwargs.pop('twitter_followers', 0)
self.instance.twitter_followers = twitter_followers
super(Evangelized, self).save(args, kwargs)
And then in the view just have to call in this way:
form.save(twitter_followers=250)
So I'm trying to create a new feed within the Admin page and its
crashing with the error IntegrityError: lifestream_feed.lifestream_id
may not be NULL, form['lifestream'] is set but
form.instance.lifestream is not.
form.fields even shows that lifestream is a django.forms.models.ModelChoiceField
Here is the code:
class FeedCreationForm(forms.ModelForm):
class Meta:
model = Feed
exclude = ['name', 'domain', 'fetchable']
def parse_feed(self, feed_url):
feed = feedparser.parse(feed_url)
# Does the feed have errors
if feed['bozo']:
if feed['feed'].has_key("links"):
for link in feed['feed']['links']:
if link["type"] == "application/rss+xml":
feed = self.parse_feed(link['href'])
if not feed['bozo']:
return feed
else:
return feed
return None
def clean(self):
"""
Checks to make sure a feed url is valid and gets the feed
title
and domain.
"""
feed_url = self.cleaned_data.get('url')
if not feed_url:
# Feed url was not validated by the field validator
return
feed = self.parse_feed(feed_url)
if feed:
feed_url = feed['url']
self.cleaned_data['url'] = feed_url
else:
# the feed was not parsed correctly.
import logging
self._errors['url'] = ErrorList(["This is not a valid
feed: %s" % feed['bozo_exception']])
logging.error(feed['bozo_exception'])
# This field is no longer valid. Remove from cleaned_data
del self.cleaned_data['url']
return
# Check if the feed has a title field
feed_info = feed.get('feed')
if not feed_info.get('title'):
self._errors['url'] = ErrorList(["This is not a valid
feed: The feed is empty"])
# This field is no longer valid. Remove from cleaned_data
del self.cleaned_data['url']
return
self.cleaned_data['name'] = feed_info['title']
self.instance.name = self.cleaned_data['name']
self.cleaned_data['domain'] = get_url_domain(feed_url)
self.instance.domain = self.cleaned_data['domain']
return self.cleaned_data
class FeedAdmin(admin.ModelAdmin):
list_display = ('name', 'lifestream', 'domain', 'fetchable')
list_filter = ('domain', 'lifestream')
actions = ['make_fetchable', 'make_unfetchable']
add_form = FeedCreationForm
model = Feed
def make_unfetchable(self, request, queryset):
queryset.update(fetchable=False)
make_unfetchable.short_description = _(u"Mark as unfetchable")
def make_fetchable(self, request, queryset):
queryset.update(fetchable=True)
make_fetchable.short_description = _(u"Mark as fetchable")
def add_view(self, request):
if not self.has_change_permission(request):
raise PermissionDenied
if request.method == 'POST':
form = self.add_form(request.POST)
if form.is_valid():
new_feed = form.save()
msg = _('The %(name)s "%(obj)s" was added
successfully.') % {'name': 'user', 'obj': new_feed}
self.log_addition(request, new_feed)
if "_addanother" in request.POST:
request.user.message_set.create(message=msg)
return HttpResponseRedirect(request.path)
elif '_popup' in request.REQUEST:
return self.response_add(request, new_feed)
else:
request.user.message_set.create(message=msg + ' '
+ ugettext("You may edit it again below."))
# TODO: use reversed url
return HttpResponseRedirect('../%s/' %
new_feed.id)
else:
form = self.add_form()
return render_to_response('admin/lifestream/feed/
add_form.html', {
'title': _('Add feed'),
'form': form,
'is_popup': '_popup' in request.REQUEST,
'add': True,
'change': False,
'has_add_permission': True,
'has_delete_permission': False,
'has_change_permission': True,
'has_file_field': False,
'has_absolute_url': False,
'auto_populated_fields': (),
'opts': self.model._meta,
'save_as': False,
#'username_help_text': self.model._meta.get_field
('username').help_text,
'root_path': self.admin_site.root_path,
'app_label': self.model._meta.app_label,
}, context_instance=template.RequestContext(request))
def queryset(self, request):
return self.model.objects.feeds()
admin.site.register(Feed, FeedAdmin)
class Lifestream(models.Model):
"""
A lifestream. Lifestreams can be created per user.
"""
site = models.ForeignKey(Site, verbose_name=_(u"site"))
user = models.ForeignKey(User, verbose_name=_(u"user"))
slug = models.SlugField(_("slug"), help_text=_('Slug for use in
urls (Autopopulated from the title).'), blank=True)
title = models.CharField(_("title"), max_length=255)
def __unicode__(self):
return self.title
class FeedManager(models.Manager):
''' Query only normal feeds. '''
def feeds(self):
return super(FeedManager, self).get_query_set()
def fetchable(self):
return self.feeds().filter(fetchable=True)
class Feed(models.Model):
'''A feed for gathering data.'''
lifestream = models.ForeignKey(Lifestream, verbose_name=_
('lifestream'))
name = models.CharField(_("feed name"), max_length=255)
url = models.URLField(_("feed url"), help_text=_("Must be a valid
url."), verify_exists=True, max_length=1000)
domain = models.CharField(_("feed domain"), max_length=255)
fetchable = models.BooleanField(_("fetchable"), default=True)
# The feed plugin name used to process the incoming feed data.
plugin_class_name = models.CharField(_("plugin name"),
max_length=255, null=True, blank=True, choices=getattr(settings,
"PLUGINS", PLUGINS))
objects = FeedManager()
def __unicode__(self):
return self.name
Its not returning the empty returns, its reaching the return self.cleaned_data:
-> return self.cleaned_data
(Pdb) list
85 self.cleaned_data['name'] = feed_info['title']
86 self.instance.name = self.cleaned_data['name']
87 self.cleaned_data['domain'] = get_url_domain(feed_url)
88 self.instance.domain = self.cleaned_data['domain']
89
90 -> return self.cleaned_data
91
92 class FeedAdmin(admin.ModelAdmin):
93 list_display = ('name', 'lifestream', 'domain', 'fetchable')
94 list_filter = ('domain', 'lifestream')
95 actions = ['make_fetchable', 'make_unfetchable']
(Pdb) self.cleaned_data
{'url': u'http://twitter.com/statuses/user_timeline/6166742.rss', 'domain': u'twitter.com', 'lifestream': <Lifestream: Social>, 'name': u'Twitter / sontek', 'plugin_class_name': u'lifestream.plugins.twitter.TwitterPlugin'}
I believe the problem is in your clean() method.
The general clean() method (as opposed to field specific clean methods like clean_domain()) must return the cleaned_data dictionary (minus any fields which do not validate), and you have at least 3 returns in your clean method that do not return anything.
See here
Turns out this is a bug in HEAD of django