Django - edit various number of formset and each form has own related values - django-views

I'm lost in django formsets. I tried many variations and none works as I need. Maybe it is a little bit confusing what my models are :)
What do I want to do? I need to create a view that displays all AssessParameters related to KapTSI and my problem is editing fields [assessment_requirements, value, finding]. Maximum what is was able to solve by using formset was editing those fields but how to display only the assessment_requirements those are related to edited parameter and to all parameters? And the bonus if there is a way with using CBV?
Models.py
class AssessParameter(models.Model):
application = models.ForeignKey(Application, on_delete=models.CASCADE, blank=True, null=True)
parameter = models.ForeignKey(Parameter, on_delete=models.DO_NOTHING)
requirement = models.TextField(blank=True)
assessment_requirements = models.ManyToManyField(Requirement, related_name="assessments", blank=True)
value = models.TextField(blank=True, null=True)
finding = models.ForeignKey(Finding, on_delete=models.DO_NOTHING)
note = models.TextField(blank=True)
documents = models.CharField(max_length=1, blank=True)
class KapTsi(models.Model):
title = models.CharField(max_length=150)
number = models.CharField(max_length=20)
tsi = models.ManyToManyField(Standard, related_name="tsis")
def __str__(self):
return f"{self.number} | {self.title}"
class ParameterGroup(models.Model):
title = models.CharField(max_length=150)
kap_tsi = models.ForeignKey(KapTsi, models.DO_NOTHING)
def __str__(self):
return f"{self.kap_tsi} {self.title}"
class Parameter(models.Model):
parameter_group = models.ForeignKey(ParameterGroup, on_delete=models.DO_NOTHING)
title = models.CharField(max_length=255)
standards = models.ManyToManyField(Standard, through="Specification", blank=True)
description = models.TextField(blank=True)
active = models.BooleanField(default=True)
def __str__(self):
return self.title
foms.py
class AssessParameterForm(forms.ModelForm):
class Meta:
model = AssessParameter
exclude = ['parameter', 'requirement', 'application']
AssessmentParameterFormSet = modelformset_factory(AssessParameter, form=AssessParameterForm, extra=0)
last try: views.py
def assessment_group(request, pk, slug, group):
application = Application.objects.get(id=pk)
group = ParameterGroup.objects.get(id=group)
assessments = AssessParameter.objects.filter(application=application).filter(parameter__parameter_group=group)
parameter = Requirement.objects.filter(parameter__parameter_group=group)
formset = AssessmentParameterFormSet(instance=assessments)
# for form in formset:
# form.fields['assessment_requirements'].queryset = parameter
context = {
'application': application,
'formset': formset,
}
return render(request, 'assessment/assessment-group.html', context)

Related

Why can not I submit a double form to the database

I created a form view and when I want to save a form with two modules I see "IntegrityError". Please help, Thank you in advance
class Place(models.Model):
LocalName = models.CharField('Nazwa Lokalu', max_length=200)
slug = models.SlugField('Link', max_length=100, default="")
LocalImg = models.ImageField('Zdjęcie Lokalu',
upload_to='Place/static/locals/img', blank=True, max_length=20000)
LocalAdress = models.CharField('Adres', max_length=500)
LocalNumberPhone = models.CharField('Numer telefonu', max_length=9)
LocalHours = models.TextField(verbose_name='Godziny otwarcia',
max_length=20000)
def get_aboslute_url(self):
return reverse("place:place_create", kwargs={'id': self.id})
class Meta:
verbose_name = "Lokal"
verbose_name_plural = "Lokale"
def __str__(self):
return self.LocalName
class Menu(models.Model):
place = models.ForeignKey(Place, on_delete=models.CASCADE,
related_name="place", default="")
Dinner = models.CharField("Nazwa potrawy",blank=True, default="",
max_length=200)
DinnerComponents = models.CharField("Składniki",blank=True, default="",
max_length=20009)
PizzaPrice = models.CharField("Rozmiar i cena Pizzy",
help_text="np.Mała-10zł", default="", blank=True, max_length=300)
Price = models.DecimalField("Cena",default="00", max_digits=5,
decimal_places=2)
class Meta:
verbose_name = "Menu"
verbose_name_plural = "Menu"
views.py
def create_place(request):
form = PlaceForm()
sub_form = MenuForm()
if request.POST:
form = PlaceForm(request.POST)
sub_form = MenuForm(request.POST)
if form.is_valid() and sub_form.is_valid():
place = form.save(commit=False)
place.location = sub_form.save()
place.save()
context = {
'form': form,
'sub_form': sub_form
}
return render(request, 'posts/layout.html', context)
Forms.py
class PlaceForm(forms.ModelForm):
class Meta:
model = Place
fields = ('LocalName', 'LocalAdress', 'LocalNumberPhone','LocalHours',)
class MenuForm(forms.ModelForm):
class Meta:
model = Menu
fields = ('Dinner','DinnerComponents','DinerCategory', 'Price',)
After filling in the form and clicking submit, an error will appear "NOT NULL constraint failed: posts_menu.place_id"
You have to first save a Place then assign the saved place to the Menu and finally save the menu.
if form.is_valid() and sub_form.is_valid():
place = form.save()
menu = sub_form.save(commit=False)
menu.place = place
menu.save()
That's because a Menu needs a place foreign key otherwise it cannot be saved.
(Note: why do you mix snake_case and CamelCase for your field names? It's terribly difficult to know how your model's properties are called. Python's convention is snake_case for all properties/methods/variables)

how can I increase the value of my article in another model view for example in django

So here, I would like the quantity existing of my Article model to increase when saving the Purchase model,
Here is my code in views.py that does not work!
I am still a beginner in Django. thank you in advance
example:
quantity of article in stock: 20
quantity purchased during a purchase: 5
so in the end in the database I would like to have 25 in the item warren in stock!
sorry for my english, i use google translator
def achat_form_view(request):
if (request.method == 'POST'):
form = AchatForm(request.POST,error_class=ParagraphErrorList)
if form.is_valid():
Article.quantite = Article.quantite + Achat.quantite_a
form.save(commit=True)
return redirect('manapoitra_achat')
else:
form = AchatForm()
return render(request, 'achatH.html', {'form': form})
models.py :
class Achat(models.Model):
id_article_a = models.ForeignKey(Article, on_delete=models.CASCADE)
id_fournisseur_a = models.ForeignKey(Fournisseur, on_delete=models.CASCADE)
quantite_a = models.PositiveIntegerField(max_length=4, verbose_name="Quantité(s)")
date_a = models.DateTimeField(auto_now_add=True, verbose_name="Date de création")
date_save_tara_a = models.DateField(blank=True, null=True)
def __unicode__(self):
return self.pk+' achat'
class Article(models.Model):
photo = models.FileField()
nom = models.CharField(max_length=60, verbose_name="Produit")
type = models.ForeignKey(Type, verbose_name="Type", on_delete=models.CASCADE)
categorie = models.ForeignKey(Categorie, verbose_name="Catégorie", on_delete=models.CASCADE)
prix_de_vente = models.CharField(max_length=8, verbose_name="Prix de vente")
prix_d_achat = models.CharField(max_length=8, verbose_name="Prix d'achat")
quantite = models.PositiveIntegerField(max_length=4, verbose_name="Quantité(s)")
date_a = models.DateTimeField(auto_now_add=True, verbose_name="Date de création")
date_de_perim = models.DateField(blank=True, null=True, verbose_name="Perimé(e) le")
def __str__(self):
return self.nom
The problem with your code is that Achat and Article refer to the entire class, not any specific instance. What you want to do is take the Achat created by your form, and increase the quantity of the specific Article chosen in that form. You can do this via the return value of form.save(), which is an instance of Achat.
if form.is_valid():
achat = form.save()
article = achat.id_article_a
article.quantite += achat.quantite_a
article.save()
return redirect('manapoitra_achat')
(Note, your field naming convention is very strange; there's no need to suffix with _a, but more importantly you should not name ForeignKey fields with an id_ prefix; the Django ForeignKey is not an ID, but gives you access directly to the related object. So for example id_article_a should be just article.)

django form not updating as expected

Here is my model:
class Browser(models.Model):
profile_name = models.CharField(max_length=400)
browser_type = (
('fr', 'Firefox'),
('ch', 'Chrome'),
('op', 'Opera'),
('ot', 'Other'),
)
browser_name = models.CharField(choices=browser_type, max_length=2)
device_name = models.CharField(max_length=400)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Bookmark(models.Model):
browser = models.ForeignKey(Browser, on_delete=models.CASCADE, null=True, blank=True)
title = models.TextField()
url = models.TextField()
iv = models.TextField()
salt = models.TextField()
iteration = models.IntegerField(default=1500)
tags = TaggableManager()
I only want to update certain fields, so here is the modelform
class BookmarkFormEdit(ModelForm):
class Meta:
model = Browser
exclude = ('tags', 'browser_name', 'device_name', 'profile_name')
but my problem is, values are not updating as expected . Here is the view:
def bookmark_edit(request, pk=None):
if request.method == 'POST':
bookmark = Bookmark.objects.get(pk=pk)
frm = BookmarkFormEdit(request.POST, instance=bookmark)
print(request.POST.get('iteration')) // printing correct value from front-end
if frm.is_valid():
x = frm.save()
print(x.iteration) // not saving the new value !
return JsonResponse({'status': 'created'})
else:
return JsonResponse({'error': frm.errors})
return render(request, 'bookmark_edit.html', {'pk': pk})
You are incorrectly defined model in the form. You should use Bookmark model instead of Browser.
class BookmarkFormEdit(ModelForm):
class Meta:
model = Bookmark
You may need to define fields to include/exclude as you want for this model.

How to fix such an error in Django url-routing, get_object_or_404and Slug?

How to get exactly the series that is specified in the URL, but the name of all series is the same, and they should be the same, but it takes only the URL of the series itself, that is, it searches only for the URL series, but not how, so that this series was in The series which is specified in the URL and also was in the season exactly the volume that is specified in the URL here is url
Url works fine but I can not go to the right series!
urlpatterns = [
url(r'^$', homeview, name='homeview'),
url(r'^subscribe/$', validate_email, name='subscribe'), # /series/
url(r'^(?P<serial_slug>[\w-]+)/$', post_of_serial, name='post_of_serial'), # /series/Prison_Break/
url(r'^(?P<serial_slug>[\w-]+)/(?P<season_slug>[\w-]+)/$', post_of_season, name='post_of_season'), # /series/Prison_Break/season_5/
url(r'^(?P<serial_slug>[\w-]+)/(?P<season_slug>[\w-]+)/(?P<series_slug>[\w-]+)/$', post_of_serie, name='post_of_serie'), # /series/Prison_Break/season_5/2/
]
Models
class Series(models.Model):
id = models.AutoField(primary_key=True)
rus_name = models.CharField(max_length=60)
eng_name = models.CharField(max_length=60)
slug = models.SlugField(unique=False)
serial_of_this_series = models.ForeignKey(Serial, on_delete=models.CASCADE, default=True)
season_of_this_series = models.ForeignKey(Season, on_delete=models.CASCADE, default=True)
number_of_series = models.IntegerField(default=0, blank=True, null=True)
description = models.TextField(max_length=700, blank=True, default=None)
size_of_torent_file = models.CharField(max_length=60, default=None)
link_for_dowloand_serie_in_quality_360p = models.CharField(max_length=60, default=None)
link_for_dowloand_serie_in_quality_720p = models.CharField(max_length=60, default=None)
link_for_dowloand_serie_in_quality_1080p = models.CharField(max_length=60, default=None)
rating = models.FloatField(default=0, blank=True)
is_active = models.BooleanField(default=True)
timestamp_rus = models.DateField(auto_now_add=True, auto_now=False)
updated = models.DateTimeField(auto_now_add=False, auto_now=True)
timestamp_eng = models.CharField(max_length=60)
time_of_series = models.DecimalField(max_digits=10, decimal_places=2, default=42)
def get_absolute_url(self):
return reverse('series:post_of_serie', kwargs=
{'serial_slug': self.serial_of_this_series.slug,
'season_slug': self.season_of_this_series.slug,
'series_slug': self.slug})
def __str__(self):
return "%s | %s" % (self.rus_name, self.number_of_series)
class Meta:
ordering = ["-timestamp_rus"]
verbose_name = 'Series'
verbose_name_plural = 'Series'
views.py
def post_of_serie(request, serial_slug=None, season_slug=None, series_slug=None):
serie = get_object_or_404(Series, serial_of_this_series=serial_slug, season_of_this_series=season_slug, slug=series_slug)
#series_2 = Series.objects.filter(serial_of_this_series=serial_slug, season_of_this_series=season_slug, slug=series_slug )
context = {"serie":serie,}
return render(request, 'series.html', context)
Error on the version above
ValueError at /series/Colony/Season_1/episode_1/
invalid literal for int() with base 10: 'Colony'
There was also such an option but there comes an error from such that such a name already exists. In fact the fact that the name of the series and seasons should be the same!
def post_of_serie(request, serial_slug=None, season_slug=None, series_slug=None):
serie = get_object_or_404(Series, slug=series_slug)
context = {"serie":serie,}
return render(request, 'series.html', context)
Try editing your views like this,
def post_of_serie(request, serial_slug=None, season_slug=None, series_slug=None):
serie = get_object_or_404(Series, serial_of_this_series__slug=serial_slug, season_of_this_series__slug=season_slug, slug=series_slug)
context = {"serie":serie,}
return render(request, 'series.html', context)
The serial_of_this_series is a ForeignKey to another table, so when accessing the field, django automatically provides the primary_key of the corresponding table. By looking at your error, it seems that you haven't explicitly specified the slug field as primary_key, then the auto-incrementing integer field which is provided by the django automatically is trying to match with the slug you just provided. I'd recommend to access the corresponding field in the table, like serial_of_this_series__slug, ie, slug field(or whatever the field name is) in Serial table for query filterings.

How do I map one models objects to another models objects in a view

I have a bunch of message records that I would like to assign to different taskboxes.
#models.py
class TaskBox(models.Model):
name = models.CharField(max_length=64, blank=False)
def __str__(self):
return u'%s' % (self.name)
class Admin:
pass
class InboxEntry(models.Model):
job_number = models.CharField(max_length=14, unique=False, blank=False, null=False)
job_name = models.CharField(max_length=64, unique=False, blank=False, null=False)
request = models.CharField(max_length=64, choices=PRINT_CHOICES, blank=True, null=True)
date_due = models.DateTimeField(("Due"),auto_now=False)
note = models.TextField(max_length=1000, unique=False, blank=True, null=True)
assigned_by = models.ForeignKey(UserProfile, blank=False, null=False)
box = models.ForeignKey(TaskBox)
assigned_to = models.ManyToManyField(UserProfile, related_name='name', blank=True)
status = models.CharField(max_length=30, choices=STATUS_CHOICES, default="Awaiting Action")
def __str__(self):
return u'%s %s' % (self.job_number, self.job_name)
class Admin:
pass
class Meta:
ordering = ['status']
The idea is for the template to have some generic tags like {{ for taskbox in taskboxes }} to create a separate div for each taskbox that will hold a table for that box's records. My problem is constructing the view function...
#views.py
def display_prdInboxEntry(request, id):
if request.method == 'POST':
form = PrdInboxForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('taskmanager/display/'+ id +'/')
else:
form = PrdInboxForm(request.POST)
return HttpResponseRedirect('taskmanager/display/'+ id +'/')
else:
form = PrdInboxForm()
user = request.user
**taskboxes = TaskBox.objects.all()
records_1 = InboxEntry.objects.filter(taskboxes[id]=1)
records_2 = InboxEntry.objects.filter(taskboxes[id]=2)
records_3 = InboxEntry.objects.filter(taskboxes[id]=3)
..... **
return render_to_response('taskmanager/taskmanager_view.html', {'form': form, 'taskboxes': taskboxes, 'records_1' : records_1, 'records_2' : records_2, 'records_3' : records_3, 'user': user}, context_instance=RequestContext(request))
The InboxEntry model has a field called "box" that's just a reference to the TaskBox model. I need a way to map say... TaskBox id 1 with all of the InboxEntry objects with "box = 1" so that I can populate the templates appropriately. Can I construct the function to accommodate this, or am I going about it the wrong way entirely?
It sounds like you're looking for the automatically-generated attribute for reverse lookups. You can get a QuerySet of all InboxEntries associated with a TaskBox like this:
TaskBox.objects.filter(id=1).inboxentry_set.all()
See the documentation on related objects.