I'm updating data in django, but the string data becomes tuple string when saved in the database.
#api_view(["POST"])
def cate_edit(req):
if not req.user.is_staff:
return HttpResponseNotFound()
data=jsonload(req.body)
if not has(data,["id","title","other_title","introduction"]):
return HttpResponseForbidden()
id=toNumber(data["id"])
if id==None:
return HttpResponseForbidden()
if id==0:
c=Category(
title=data["title"],
other_title=data["other_title"],
introduction=data["introduction"]
)
c.save()
return HttpResponse(c.id)
else:
c=get_object_or_404(Category,id=id)
c.title = data["title"],
c.other_title = data["other_title"],
c.introduction = data["introduction"]
c.save()
return HttpResponse(c.id)
The problem happened in the final else, I can make sure the data is a valid and normal dict, such as
{'id': 1, 'title': '1', 'other_title': '2', 'introduction': '3'}
but after this save process, the data in database is
title: "('1',)"
other_title:"('2',)"
introduction: '3'
introduction is correct actually.
Additionally, here is the model of category
class Category(models.Model):
title = models.CharField(max_length=50)
other_title = models.CharField(max_length=50,blank=True)
image = models.ImageField(blank=True,null=True,upload_to=file_path)
introduction = models.TextField(default="",blank=True)
last_modified = models.DateTimeField(auto_now=True)
def __str__(self):
return self.title
Thanks
Update:
It's cool to use query and update, but why above situation happens? I used to do like that but works fine.
You have commas at the end of your assignments.
c.title = data[“title”],
Should be:
c.title = data[“title”]
Related
I'm running into a small problem with writing a unit test for a Django form. I really just want to check the is_valid() method and have seen examples but my code isn't working and after a day or so of reading up on Google I've yet to find the answer I'm looking for. Below is the code for the forms.py and test_forms.py
forms.py
class DataSelectForm(forms.Form):
#these are done in the init funct.
result_type = forms.ChoiceField(widget=forms.Select(attrs={'class': 'field-long'}))
band_selection = forms.MultipleChoiceField(widget=forms.SelectMultiple(attrs={'class': 'multiselect field-long'}))
title = forms.CharField(widget=forms.HiddenInput())
description = forms.CharField(widget=forms.HiddenInput())
def __init__(self, result_list=None, band_list=None, *args, **kwargs):
super(DataSelectForm, self).__init__(*args, **kwargs)
if result_list is not None and band_list is not None:
self.fields["result_type"] = forms.ChoiceField(choices=result_list, widget=forms.Select(attrs={'class': 'field-long'}))
self.fields["band_selection"] = forms.MultipleChoiceField(widget=forms.SelectMultiple(attrs={'class': 'multiselect field-long'}), choices=band_list
test_forms.py
def test_data_select_form(self):
results = ResultType.objects.all()
results_value = []
for result in results:
results_value.append(result.result_type)
bands = SatelliteBand.objects.all()
bands_value = []
for band in bands:
bands_value.append(band.band_name)
form_data = {'result_type': results_value, 'band_selection': bands_value, 'title': 'a title', 'description': 'some description'}
form = DataSelectForm(data = form_data)
print(form['title'].value())
print(form['description'].value())
print(form['result_type'].value())
print(form['band_selection'].value())
self.assertTrue(form.is_valid())
The only thing I get when I run the test case is "AssertionError: False is not true" I understand the error, just not why I'm getting it. I'm passing in all the data and I can see it when I run the print statements. I've tried taking the result_type and band_selection and passing it into the constructor instead of it being a part of the form_data but that didn't work either. What am I missing?
You need to pass result_list and band_list when you construct your form.
# These aren't the actual choices you want, I'm just showing that
# choices should be a list of 2-tuples.
result_list = [('result1', 'result1'), ('result2', 'result2'), ...]
band_list = [('band1', 'band1'), ('band2', 'band2'), ...]
DataSelectForm(result_list=result_list, band_list=band_list, data=form_data)
If you don't pass the values to the form, then you don't set the choices for the fields. If the fields don't have any choices, then the values in the data dict cannot be valid, so the form will always be invalid.
I'm a newbie Django user, struggling with submitting form data to the database. So that I can generate dynamic forms I am using a non-ModelForm form to capture field data.
I'm commented out validation for now but I am trying to capture the POST data from the form to the database. The latest 'draft' of my views.py code is as follows - most interested in format from form_to_save = Scenario(...):
def scenario_add(request, mode_from_url):
urlmap = {
'aviation': 'Aviation',
'maritime': 'Maritime',
'international_rail': 'International Rail',
'uk_transport_outside_london': 'UK Transport (Outside London)',
'transport_in_london': 'Transport in London',
}
target_mode = urlmap[mode_from_url]
m = Mode.objects.filter(mode=target_mode)
tl = m[0].current_tl.threat_l
scenario_form = ScenarioForm(request.POST or None, current_tl=tl, mode=target_mode)
if request.method == 'POST':
#if scenario_form.is_valid():
form_to_save = Scenario(
target = Target(descriptor = scenario_form.fields['target']),
t_type = ThreatType(t_type = scenario_form.fields['t_type']),
nra_reference = NraReference(nra_code = scenario_form.fields['nra_reference']),
subt = scenario_form.fields['subt'],
ship_t = ShipType(ship_t = scenario_form.fields['ship_t']),
likelihood = scenario_form.fields['likelihood'],
impact = scenario_form.fields['impact'],
mitigation = scenario_form.fields['mitigation'],
compliance_score = scenario_form.fields['compliance_score'],
notes = scenario_form.fields['notes']
)
form_to_save.save()
# This needs to be changed to a proper redirect or taken to
# a scenario summary page (which doesn't yet exit.)
return render(request, "ram/new_scenario_redirect.html", {
'scenario_form': scenario_form,
'mode': mode_from_url,
'mode_proper': target_mode
})
else:
# if there is no completed form then user is presented with a blank
# form
return render(request, 'ram/scenario_add.html', {
'scenario_form': scenario_form,
'current_tl': tl,
'mode': mode_from_url,
'mode_proper': target_mode
})
Any advice gratefully received. Many thanks.
You've commented out the is_valid check, for some reason. You need that: as well as checking for validity, it also populates the form's cleaned_data dictionary which is what you should be getting the data from to create your object. (And don't call that object "form_to_save": it's a model instance, not a form).
if request.method == 'POST':
if scenario_form.is_valid():
scenario = Scenario(
target = Target(descriptor=scenario_form.cleaned_data['target']),
t_type = ThreatType(t_type = scenario_form.cleaned_data['t_type'])
...etc
Plus, you should move the final "return render" call out of the else block, so that it is caught when the form is not valid, to show any errors.
However, as petkostas says, you would almost certainly be better off using an actual ModelForm in the first place.
You can add custom options by overriding the init function in your form. For example:
class SomeForm(forms.Form):
department = forms.ChoiceField(widget=forms.Select, required=True)
...
def __init__(self, *args, **kwargs):
super(SomeForm, self).__init__(*args, **kwargs)
self.fields['department'].choices = Department.objects.all().order_by('department_name).values_list('pk', 'department_name')
You can also change the queryset in the init function:
where Department is a foreign key for example
queryset = Department.objects.filter(your logic)
self.fields['department'].queryset = queryset
I'm a beginner, so please go easy on me. I am working on a script so that I don't have to keep entering in data when I decide to drop the database. My entire script works well, except when I'm dealing with a one-to-many relationship. It will not save to the database. Can anyone tell me what I am doing wrong or point me in the right direction?
SCRIPT:
try:
pmod.Instrument.objects.get(title='kjkjsdfsadfs')
except pmod.Instrument.DoesNotExist:
u = pmod.Instrument()
u.title = 'Bach 42 Trombone'
u.price = 550.00
u.soundDescription = 'Good'
u.functionalityDescription = 'Good'
u.damageDescription = 'Good'
u.accessoryDescription = 'Good'
u.customerName = 'Jake'
u.customerEmail = 'ks#gmail.com'
u.instrumentCategory = 1
print('Good2')
u.save()
print('Instrument1 saved')
MODEL:
class Category(models.Model):
instrumentCategory=models.CharField(max_length=50,blank=True,null=True)
def __str__(self):
return self.instrumentCategory
class Instrument(models.Model):
title = models.CharField(help_text='title',max_length=50,blank=True,null=True)
price = models.DecimalField(max_digits=8, decimal_places=2)
soundDescription=models.CharField(max_length=1000,blank=True,null=True)
functionalityDescription=models.CharField(max_length=1000,blank=True,null=True)
damageDescription=models.CharField(max_length=1000,blank=True,null=True)
accessoryDescription=models.CharField(max_length=1000,blank=True,null=True)
customerName=models.CharField(max_length=50,blank=True,null=True)
customerEmail=models.EmailField(max_length=254,help_text='Enter valid email address')
instrumentCategory=models.ForeignKey(Category)
u.instrumentCategory = 1
That's not how a models.ForeignKey field works in Django. You need to get an instance of the Category object and assign that to u.instrumentCategory.
u.instrumentCategory = pmod.Category.objects.get(id=1)
You may try :
u.instrumentCategory_id = 1
I have an Openstack-powered, Django-modified application that shows the disk images and snapshots available for a user to launch. The user currently sees both snapshots they created and ones they did not. I would like to separate the current table into two based on whether they are owned by the user or not.
My two table definitions are as follows (note I altered row_actions accordingly):
class UserSnapshotsTable(OldSnapshotsTable):
cloud = tables.Column(get_cloud, verbose_name=_("Cloud"))
class Meta:
name = "usersnapshots"
verbose_name = _("User Snapshots")
table_actions = (DeleteSnapshot,)
row_actions = (LaunchSnapshot, LaunchCluster, EditImage, DeleteSnapshot)
pagination_param = "snapshot_marker"
row_class = UpdateRow
status_columns = ["status"]
class OtherSnapshotsTable(OldSnapshotsTable):
cloud = tables.Column(get_cloud, verbose_name=_("Cloud"))
class Meta:
name = "othersnapshots"
verbose_name = _("Other Snapshots")
table_actions = (DeleteSnapshot,)
row_actions = (LaunchSnapshot, LaunchCluster)
pagination_param = "snapshot_marker"
row_class = UpdateRow
status_columns = ["status"]
I have altered the HTML template to pull the "UserSnapshotsTable" and "OtherSnapshotsTable" tables (I copied the original table and renamed both), but both full tables still generate under the respective headings. There are two functions generating the data:
def get_usersnapshots_data(self):
req = self.request
marker = req.GET.get(UserSnapshotsTable._meta.pagination_param, None)
try:
usersnaps, self._more_snapshots = api.snapshot_list_detailed(req,
marker=marker)
except:
usersnaps = []
exceptions.handle(req, _("Unable to retrieve user-owned snapshots."))
return usersnaps
def get_othersnapshots_data(self):
req = self.request
marker = req.GET.get(OtherSnapshotsTable._meta.pagination_param, None)
try:
othersnaps, self._more_snapshots = api.snapshot_list_detailed(req,
marker=marker)
except:
othersnaps = []
exceptions.handle(req, _("Unable to retrieve non-user-owned snapshots."))
return othersnaps
There are also Edit/Delete options defined for images, and imported for snapshots, that seem to have a key comparison. Here's the "Delete" one (line 7):
class DeleteImage(tables.DeleteAction):
data_type_singular = _("Image")
data_type_plural = _("Images")
def allowed(self, request, image=None):
if image:
return image.owner == request.user.tenant_id
# Return True to allow table-level bulk delete action to appear.
return True
def delete(self, request, obj_id):
api.image_delete(request, obj_id)
How can I separate those tables out? This is my first time asking a question here, so please let me know if I can provide further information. Apologies for the length of it.
As far as I see you are using glanceclient. If that so you can use extra_filters parameter of snapshot_list_detailed() to filter only user images like this:
usersnaps, self._more_snapshots = api.snapshot_list_detailed(
req,
marker = marker,
extra_filters = {"owner": "user_name"}
)
Under cover snapshot_list_detailed uses GET images of Openstack Image Service API.
Currently I have the following code:
class User(db.Model):
field_names = db.StringListProperty(indexed=False)
field_values = db.StringListProperty(indexed=False)
field_scores = db.ListProperty(int, indexed=False)
def fields_add(user_key_name, field_name, field_value, field_score):
user = User.get(user_key_name)
if user:
try:
field_index = user.field_names.index(field_name) # (1)
user.field_values[field_index] = field_value
user.field_scores[field_index] = field_score
except ValueError:
# field wasn't added to the list before
user.field_names.append(field_name)
user.field_values.append(field_value)
user.field_scores.append(field_score)
user.put()
It works well, but I would like to optimize that - serialize field_name, field_value and field_score and store in one BlobProperty:
class User(db.Model):
fields = db.ListProperty(indexed=False)
f = {
'f': field_name,
'v': field_value,
's': field_score,
}
user.fields = simplejson.dumps(f)
But how should code (1) look like with such approach? How to find record for update?
If user.fields is a list of dicts where 'f' is the field name, this is one possible answer to your immediate question:
field_index = [field['f'] for field in user.fields].index(field_name)
It's not immediately clear why your revision is more optimal in your case, but I'll take your word for it. :)
You can serialize objects with json or pickle.
So for instance. If your model holds a property : udata = db.BlobProperty()
The serialize an object like : ..udata = pickle.dumps(object).