OpenStack Horizon - LinkAction is not passing data to the view - django-views

I'm having an issue in one of my data tables - when the table's LinkAction is clicked, it would not pass the data to the corresponding View.
I need to have an experience identical to what you get when you choose to update an existing Network record. There, when you click on the "Edit" row action, the corresponding Form is populated with that Network data.
In my case, I have a custom dashboard/panel/tab/table. So, when I click on the "Edit" link action within that table row, I do get my Form to show, but it is not passed any data from the row..
Here is my table and action (tables.py):
class UpdateWorkload(tables.LinkAction):
name = "update"
verbose_name = _("Edit Workload")
url = "update"
classes = ("ajax-modal",)
icon = "pencil"
class WorkloadsTable(tables.DataTable):
name = tables.Column("name",
verbose_name=_("Name"))
description = tables.Column("description", verbose_name=_("Description"))
image = tables.Column("image", verbose_name=_("Image"))
flavor = tables.Column("flavor", verbose_name=_("Flavor"))
class Meta:
name = "workloads_table"
verbose_name = _("Workloads Table")
table_actions = (CreateNewWorkload,
UpdateWorkload,
DeleteWorkload)
row_actions = (UpdateWorkload, DeleteWorkload)
Here is my update view (views.py):
class UpdateView(forms.ModalFormView):
form_class = project_forms.UpdateWorkload
template_name = 'update_workload.html'
context_object_name = 'workload'
success_url = reverse_lazy('index')
And here is my form (forms.py):
class UpdateWorkload(forms.SelfHandlingForm):
name = forms.CharField(max_length="255", label=_("Workload Name"))
description = forms.CharField(widget=forms.Textarea,
label=_("Description"), required=False)
image_choices = []
images = forms.ChoiceField(label=_("Images"), choices=image_choices)
flavor_choices = []
flavors = forms.ChoiceField(label=_("Flavors"), choices=flavor_choices)
def handle(self, request, data):
try:
# here we will need to call update on http://127.0.0.1:8000/workloads/ and pass the id
workload = 0
msg = _('Workload was successfully updated.')
messages.success(request, msg)
# return workload
except Exception:
msg = _('Failed to update Workload %s')
redirect = reverse(self.failure_url)
exceptions.handle(request, msg, redirect=redirect)
What can I do to make this table and view pass the row data to the form?

Related

How to show user's information (special ID, firstName, lastname) in another template after successfully form submission in Django

How to show user's information (special ID, firstName, lastname) in another template after successful form submission in Django.
I have a form to ask users information(general information, Education, experience) and I give random unique test_id. After the user-submitted the form successfully, I have to show his/her test_id to memorize.
I didn't have an idea about view form. My solution is a bit stupid
My model:
class UserForm_uz(models.Model):
test_id = models.CharField(default=random_string,max_length=5,editable=False,unique=True)
rasm = models.ImageField(upload_to='media/rasmlar',null=True,blank=True)
jobName = models.ForeignKey(Job, on_delete=models.CASCADE)
lastName = models.CharField(max_length=200)
firstName = models.CharField(max_length=200)
middleName = models.CharField(max_length=200,blank=True,null=True)
birthData = models.DateField()
nation = models.CharField(max_length=50,blank=True,null=True)
My view:
class FormAfterView(View):
def get(self,request):
obj = UserForm_uz.objects.all().last()
test_id = obj.test_id
firstName = obj.firstName
lastName = obj.lastName
return render(request,"formafter.html",{"test_id":test_id,"firstName":firstName,"lastName":lastName})
You can pass your queryset directly to your Django template and use that queryset to display data accordingly. So your function will like this...
View
class FormAfterView(View):
def get(self,request):
obj = UserForm_uz.objects.all().last()
context = {
'user_details': obj,
}
return render(request,"formafter.html", context)
Django Templates
<p>{{user_details.test_id}}</p>
<p>{{user_details.firstname}}</p>
........
Also, you should try to pass parameters with URLs to fetch data from models.
Using obj = UserForm_uz.objects.all().last() does work but it's not the preferred way and sometimes it can give you wrong data if you placed an ordering query in your models class. What you can do is
URL file
urlpatterns = [
path("form_after_view/<string:main_id>", views.FormAfterView, name="form_after_view"),
]
Form save view
class FormAfterView(View):
def post(self,request):
form = Formclass(request.POST)
if form.is_valid():
form.save()
return redirect('form_after_view', form.main_id)
Next Step View
class FormAfterView(View):
def get(self,request, main_id):
obj = UserForm_uz.objects.get(main_id=main_id)
This will give you the exact instance that you just saved in previous step view.

Customize admin import forms

I want to add an additional field to my Import-Form on the Admin page.
I did everything the Docs say but the entered values for year and calender_week wont show up.
resources.py
class ForecastListResource(resources.ModelResource):
year = fields.Field(column_name="Jahr", attribute="year")
calender_week = fields.Field(column_name="Kalenderwoche", attribute="calender_week")
brand = fields.Field(column_name="Marke", attribute="brand")
material = fields.Field(column_name="Material", attribute="material")
material_short_text = fields.Field(column_name="Materialkurztext", attribute="material_short_text")
gmc = fields.Field(column_name="GMC", attribute="gmc")
gmc_text = fields.Field(column_name="GMC Text", attribute="gmc_text")
bed_date = fields.Field(column_name="BedTermin", attribute="bed_date")
bed_amount = fields.Field(column_name="BedMenge", attribute="bed_amount")
bed_week = fields.Field(column_name="BedWoche", attribute="bed_week")
code_last_bed_week = fields.Field(column_name="Code letzte KW", attribute="code_last_bed_week")
fabric_number = fields.Field(column_name="Stoffnummer", attribute="fabric_number")
print_stage_3 = fields.Field(column_name="Druckstufe 3", attribute="print_stage_3")
average_filling = fields.Field(column_name="Mittelwert Abfüllung", attribute="average_filling")
net = fields.Field(column_name="Netto", attribute="net")
class Meta:
model = ForeCastList
use_bulk = True
skip_unchanged = True
forms.py
class ForecastDoDImportFormMixin(forms.Form):
calender_week = forms.IntegerField(label="Kalenderwoche", required=True)
year = forms.IntegerField(label="Jahr", required=True)
class ForecastDoDImportForm(ForecastDoDImportFormMixin, ImportForm):
pass
class ForecastDoDConfirmImportForm(ForecastDoDImportFormMixin, ConfirmImportForm):
pass
admin.py
#admin.register(ForeCastList)
class ForeCastList(ImportExportModelAdmin):
resource_class = ForecastListResource
def get_import_form(self):
return ForecastDoDImportForm
def get_confirm_import_form(self):
return ForecastDoDConfirmImportForm
def get_form_kwargs(self, form, *args, **kwargs):
if isinstance(form, ForecastDoDImportForm):
if form.is_valid():
kwargs.update({"calender_week": form.cleaned_data["calender_week"], "year": form.cleaned_data["year"]})
return kwargs
def get_import_data_kwargs(self, request, *args, **kwargs):
print(kwargs)
return super().get_import_data_kwargs(request, *args, **kwargs)
Import-Form
Result
-> related Part from the Doc´s:
https://django-import-export.readthedocs.io/en/latest/getting_started.html#customize-admin-import-forms
If I understand correctly, you want to select a value from a dropdown and have that inserted for all rows. This means that if there is a value for 'Jahr' in the import file, this will be ignored in favour of the value selected from the dropdown.
Setting an import field to the selection in the dropdown can be achieved by assigning the value of the dropdown onto the instance of the object to be imported as follows. (I've used the single field 'year' instead of 'Jahr' and 'Kalenderwoche' but you can update your implementation along the same lines).
class ForecastListResource(resources.ModelResource):
year = fields.Field(column_name="Jahr", attribute="year")
# (other fields removed for brevity
def after_import_instance(self, instance, new, row_number=None, **kwargs):
# override to set the value of the dropdown onto the row instance
instance.year = kwargs.get("year")
class Meta:
model = ForeCastList
use_bulk = True
skip_unchanged = True
Declare the ModelAdmin class to read the 'year' value from the form:
#admin.register(ForeCastList)
class ForeCastList(ImportExportModelAdmin):
resource_class = ForecastListResource
# other methods removed
def get_import_data_kwargs(self, request, *args, **kwargs):
form = kwargs.get('form')
if form:
return {"year": form.cleaned_data["year"]}
return dict()
I was able to complete this in the example app:

Need to know where is the problem with bulk import and how to fix it

I'm building an app with Django and I need to import data using django-import-export.
I'm using the bulk import of this last package. I can import the data the first time, but when I try to import it the second time an error occurred. The expected behavior is to not import data and don't cause an error.
My view looks something like this(I simplified the code below since in the actual view I have four resources and four files to import)
def complete_import(request):
if request.method == 'POST':
offering_resource = OfferingResource()
issuer_resource = IssuerResource()
offering_dataset = Dataset()
issuer_dataset = Dataset()
offering = request.FILES['offering']
issuer = request.FILES['issuer']
offering_data = offering_dataset.load(offering.read().decode('utf-8'), format='csv', delimiter='\t', headers=True)
issuer_data = issuer_dataset.load(issuer.read().decode('utf-8'), format='csv', delimiter='\t', headers=True)
offering_data.append_col(get_quarter, header='quarter')
issuer_data.append_col(get_quarter, header='quarter')
offering_result = offering_resource.import_data(offering_data, dry_run=True, raise_errors=True)
issuer_result = issuer_resource.import_data(issuer_data, dry_run=True, raise_errors=True)
if not offering_result.has_errors() and issuer_result.has_errors():
offering_resource.import_data(offering_dataset, dry_run=False)
del offering_result
issuer_resource.import_data(issuer_dataset, dry_run=False)
del issuer_result
else:
print('an error occurred')
return render(request, 'index.html')
My resource looks like this:
class OfferingResource(ModelResource):
accession_number = Field(
attribute='company',
column_name='ACCESSIONNUMBER',
widget=ForeignKeyWidget(Company, 'accession_number'))
quarter = Field(attribute='quarter')
# other fields
class Meta:
model = Offering
use_bulk = True
skip_diff = True
batch_size = 1000
import_id_fields = ('accession_number', 'quarter')
def before_import_row(self, row, row_number=None, **kwargs):
total_offering_amount = row.get('TOTALOFFERINGAMOUNT')
try:
row['TOTALOFFERINGAMOUNT'] = int(total_offering_amount)
except ValueError:
row['TOTALOFFERINGAMOUNT'] = -1
Company.objects.get_or_create(accession_number=row.get('ACCESSIONNUMBER'))
class IssuerResource(ModelResource):
accession_number = Field(attribute='company',
column_name='ACCESSIONNUMBER',
widget=ForeignKeyWidget(Company, 'accession_number'))
quarter = Field(attribute='quarter')
issuer_seq_key = Field(attribute='issuer_seq_key', column_name='ISSUER_SEQ_KEY')
# other filds
class Meta:
model = Issuer
use_bulk = True
skip_diff = True
batch_size = 1000
import_id_fields = ('accession_number', 'issuer_seq_key', 'quarter')
When I comment the use_bulk in the Meta class I get the expected behavior.
Edit
The error that I get (I forgot to add it before)
bulk_update() cannot be used with primary key fields.
I want to know how can I fix this?
Presumably you are using a primary key field as one of the fields in your Resource list. You cannot use a primary key field with Django's bulk_update() (docs).
Can you remove the PK field from the list of fields? If not, is there some other unique field you can use to uniquely identify a record that should be updated.

Inconsistent behavoiur of save(commit=False) for a ModelForm in Django 2.2

I have a ModelForm that selects one field and excludes the rest, one of which is a ForeignKey that I need to populate manually before saving the form.
I'm in the process of fixing a bug that one of my views has and I'm making use of the request.session object to store information so that the GET and POST method funcions will be in synced by the session in locating the model at hand instead of separately iterating though the database to pin-point what model object the submitted data should be saved for.
I'm making use of the form_object.save(commit=False) funcionality in other places of the same view and it works as I need but for some reason there is a section of the view where it just doesn't populate the extra field before calling the eventual save() method and I get an IntegrityError for that column in the database, even if it is not null=False in my model declaration right now (and I think it'd rather should be..).
So here's my ModelForm:
class PesoFormApertura(ModelForm):
peso_apertura = forms.DecimalField(min_value=0,required=True)
class Meta:
model = Peso
fields = ('peso_apertura',)
here's the Model itself:
class Peso(models.Model):
prodotto = models.ForeignKey(ProdottoPesato,on_delete=models.CASCADE)
peso_apertura = models.DecimalField(max_digits=8,decimal_places=2, blank=False, null=True)
peso_calcolato = models.DecimalField(max_digits=8,decimal_places=2, blank=True, null=True)
peso_chiusura = models.DecimalField(max_digits=8,decimal_places=2, blank=True, null=True)
data = models.DateField(auto_now_add=True, blank = False)
def __str__(self):
return "{} - {} - {}".format(self.prodotto.nome, self.prodotto.get_categoria_display(), self.data)
def save(self, *args, **kwargs):
if self.peso_apertura == 0:
prodotto_associato = ProdottoPesato.objects.get(pk = self.prodotto.pk)
if prodotto_associato.permanente == False:
prodotto_associato.delete()
self.delete()
else:
super().save(*args, **kwargs)
else:
super().save(*args, **kwargs)
class Meta:
ordering = ['prodotto']
and here's the view part where the save() method is failing (where I placed a comment):
if not 'prodotto-da-correggere' in request.session:
for prodotto in tutti_prodotti:
pesi_questo_prodotto_oggi = prodotto.pesi_di_oggi()
for peso in pesi_questo_prodotto_oggi:
if peso.peso_apertura == None:
prodotto_da_elaborare = prodotto
peso_del_giorno = peso
break
if prodotto_da_elaborare:
finito = False
instance_peso = peso_del_giorno
form = PesoFormApertura(request.POST, instance = instance_peso)
if form.is_valid():
form.save(commit=False) # WORKS FINE
form.prodotto = prodotto_da_elaborare
form.save()
else:
form = PesoFormApertura(request.POST)
else: # HERE IS WHERE IT DOESN'T BEHAVE LIKE ABOVE
prodotto_da_elaborare = ProdottoPesato.objects.get(id=request.session['prodotto-da-correggere'])
peso_del_giorno = None
for peso in prodotto_da_elaborare.pesi_di_oggi():
if peso.peso_apertura == None or peso.peso_apertura > 0:
peso_del_giorno = peso
break
form_correzione = PesoFormApertura(request.POST, instance = peso_del_giorno)
if form_correzione.is_valid():
form_correzione.save(commit=False)
form_correzione.prodotto = prodotto_da_elaborare
form_correzione.save() # IT DOESN'T ADD THE INFORMATION TO THE COLUMN WHEN IT SAVES
request.session.flush()
The save() method works alright for the first part of the IF statement and just doesn't work for the rest of the snippet in the ELSE section.
So I'm wondering if the session has something to do with this.
When you call form.save() it returns the instance. You should modify and save that instance.
if form_correzione.is_valid():
peso = form_correzione.save(commit=False)
peso = prodotto_da_elaborare
peso.save()
You should change the other part of the view to use this approach as well. It looks like form.prodotto = prodotto_da_elaborare is having no effect, but you haven't noticed because prodotto is already set so you don't get an integrity error.

passing an html parameter to my view then using it in my object.get()

I have two parameters I wish to use to get a single row from my database and use that in my template.
my url looks like:
enter code here{{ divisions }}
my view looks like this but doesn't work:
class detailView(generic.DetailView):
model = divisiondisplay
template_name = 'wondjinainfo/detail.html'
def get_queryset(self):
divisiondisplay.objects.get(divisioncode = divisioncode,freetradezone = freetradezone)
and my model looks like:
class divisiondisplay(models.Model):
freetradezone = models.ForeignKey(ftz, on_delete=models.CASCADE)
divisioncode = models.IntegerField()
bodytext = models.TextField()
imagename = models.CharField(max_length = 25)
def __str__(self):
return self.bodytext
how can I use those two parameters to select my row
I tried this change:
divisiondisplay.objects.get(divisioncode = self.kwargs['divisioncode'],freetradezone = self.kwargs['freetradezone'])
it got me new error of: Generic detail view detailView must be called with either an object pk or a slug.
because my model needed to be searched by fields other than the keys. the detail generic view was the wrong solution. I defined my own view and used it:
def divisiondisplay_detail_view(request,freetradezone, divisioncode):
try:
sometext = divisiondisplay.objects.get(divisioncode = divisioncode, freetradezone = freetradezone)
except divisiondisplay.DoesNotExist:
raise Http404('Book does not exist')
# from django.shortcuts import get_object_or_404
# book = get_object_or_404(Book, pk=primary_key)
return render(request, 'wondjinainfo/detail.html', context={'sometext': sometext})