Add url to a field in TabularInline in Django admin - django

The questions is not actual
How can I make links from field author for TabularInline? For now I implement this (source: https://stackoverflow.com/a/10011307/9112151):
class Post(models.Model):
title = models.CharField(max_lenght=100)
author = models.ForeignKey('User', on_delete=models.CASCADE)
def add_link_field(target_model = None, field = '', link_text = unicode):
def add_link(cls):
reverse_name = target_model or cls.model.__name__.lower()
def link(self, instance):
app_name = instance._meta.app_label
reverse_path = "admin:%s_%s_change" % (app_name, reverse_name)
link_obj = getattr(instance, field, None) or instance
url = reverse(reverse_path, args = (link_obj.id,))
return mark_safe("<a href='%s'>%s</a>" % (url, link_text(link_obj)))
link.allow_tags = True
link.short_description = reverse_name + ' link'
cls.link = link
cls.readonly_fields = list(getattr(cls, 'readonly_fields', [])) + ['link']
return cls
return add_link
#add_link_field('author')
class PostInline(admin.TabularInline):
model = Post
Maybe there is built-in decision?

Set show_change_link = True on your inline to display a link to the admin change form for an inline object
class PostInline(admin.TabularInline):
model = Post
show_change_link = True

Related

select filtering and removal if they are already present in the db

look at the picture before answering me.
that group2 is inside saved in the db with the button I open a modal that allows me to save other groups in the db and I would like that the same groups no longer appear in that select if I have already added them
form.py
class EserciziForm(forms.ModelForm):
class Meta:
model = models.DatiEsercizi
exclude = ['gruppo_single']
#fields = '__all__'
class GruppiForm(forms.ModelForm):
class Meta:
model = models.DatiGruppi
exclude = ['gruppi_scheda']
views.py
def creazione(request, nome):
scheda = get_object_or_404(Schede, nome_scheda = nome)
eserciziFormSet = formset_factory(EserciziForm, extra = 0)
if request.method == "POST":
gruppo_form = GruppiForm(request.POST, prefix = 'gruppo')
if gruppo_form.is_valid():
gruppo = gruppo_form.save(commit = False)
gruppo.gruppi_scheda = scheda
gruppoName = gruppo_form.cleaned_data['dati_gruppo']
gruppo.save()
esercizi_formset = eserciziFormSet(request.POST, prefix='esercizi')
for esercizi in esercizi_formset:
esercizi_instance = esercizi.save(commit = False)
esercizi_instance.gruppo_single = get_object_or_404(DatiGruppi, gruppi_scheda = scheda.id, dati_gruppo = gruppoName)
esercizi_instance.save()
return HttpResponseRedirect(request.path_info)
else:
gruppo_form = GruppiForm(prefix = 'gruppo')
esercizi_formset = eserciziFormSet(prefix='esercizi')
context = {'scheda' : scheda, 'gruppo_form' : gruppo_form, 'esercizi_formset': esercizi_formset}
return render(request, 'crea/passo2.html', context
models.py
class DatiGruppi(models.Model):
giorni_settimana_scelta = [
("LUNEDI","Lunedì"),
("MARTEDI","Martedì"),
("MERCOLEDI","Mercoledì"),
("GIOVEDI","Giovedì"),
("VENERDI","Venerdì"),
("SABATO","Sabato"),
("DOMENICA","Domenica")
]
giorni_settimana = MultiSelectField(choices = giorni_settimana_scelta,default = '-')
dati_gruppo = models.ForeignKey(
Gruppi,on_delete = models.CASCADE, related_name = 'dati_gruppo')
gruppi_scheda = models.ForeignKey(Schede,on_delete = models.CASCADE, related_name = 'gruppi_scheda')
class Schede(models.Model):
nome_scheda = models.CharField(max_length=100)
data_inizio = models.DateField()
data_fine = models.DateField()
utente = models.ForeignKey(User, on_delete = models.CASCADE,related_name = 'utente')
You can override a form field before instantiate it like this :
views.py
from django import forms
if request.method == "POST":
# Post logic here
else:
# We try to retrieve group that the current user is not yet in.
# Not your logic, but to sum up, you have to retrieve the groups
# which had not yet been added.
# Use a filter that permit you to retrieve only groups which had not yet been added.
group_to_add = Group.objects.filter(...)
GruppiForm.base_fields['group_field'] = forms.ModelChoiceField(
queryset=group_to_add)
# Instantiate the form now
# In this form, the choices are only those contained in the group_to_add queryset
form = GruppiForm(prefix = 'gruppo')

How can i create custom validation in django model forms

I want to create a custom form validation in Django forms. I am able to do it normal Django forms but unable to do it in model forms.
my Django form code is
class Post_Article(forms.Form):
title = forms.CharField(label = 'Title',max_length = 100)
abstract = forms.CharField(widget = forms.Textarea, max_length = 300)
body = forms.CharField(widget = forms.Textarea)
image = forms.ImageField(required = False)
hash_tags = forms.CharField(max_length = 50,required = False)
def no_of_hash_tags(self):
cleaned_data = super().no_of_hash_tags()
tags = cleaned_data.get('hash_tags')
if tags:
tags = split(str(tags))
if len(tags) > 5:
raise forms.ValiadationError('Maximum 5 tags are allowed')
the Django model is
class PostsArticle(models.Model):
title = models.CharField(max_length=255)
pub_date = models.DateTimeField(default= timezone.now)
abstract = models.TextField()
body = models.TextField()
image = models.ImageField(upload_to=('images/'),blank=True)
user = models.ForeignKey(User , on_delete = models.CASCADE)
hash_tags = models.CharField(max_length = 50,blank= True)
def _str_(self):
return self.title
def get_absolute_url(self):
return reverse('home')
def summary(self):
return self.absract[:200]
def pub_date_pretty(self):
return self.pub_date.strftime('%b %e %Y')
def link_tags(self):
cleaned_data = super().link_tags
tags = cleaned_data.get['hash_tags']
for tag in tags:
hashing(tag,"PostsArticle")
After some discussion on stack overflow I updates my Django forms to
class Post_Article(forms.ModelForm):
title = forms.CharField(label = 'Title',max_length = 100)
abstract = forms.CharField(widget = forms.Textarea, max_length = 300)
body = forms.CharField(widget = forms.Textarea)
image = forms.ImageField(required = False)
hash_tags = forms.CharField(max_length = 50,required = False)
class Meta:
model = PostsArticle
fields=("title", "abstract", "body", "image", "hash_tags")
def clean(self)
:
cleaned_data=super(Post_Article, self).clean()
tags = cleaned_data.get("hash_tags")
if tags:
tags = split(str(tags))
if len(tags) > 5:
raise forms.ValidationError('Maximum 5 tags are allowed')
return cleaned_data
Now I am unable to get how can I use it with my current class used in views.py
class FeedUpdateView(LoginRequiredMixin, UserPassesTestMixin , UpdateView):
model = FeedPosts
fields= ['body', 'image']
template_name= 'post/edit_Feed.html'
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
def test_func(self):
Posts = self.get_object()
if self.request.user == Posts.user:
return True
return False
I want to use my Django forms code instead of creating view from my model directly. I want to do it because I want to have some custom validation of a field as given in my forms code
kindly help how can I add form validation to my model
Cleaning a specific field attribute, you would have to call clean_<field_name>.
class Post_ArticleForm(ModelForm):
class Meta:
model = PostsArticle
fields = ['abstract', 'title', 'body', 'image', 'hash_tags']
def clean_hash_tags(self):
cleaned_data = super().clean_hash_tags()
tags = self.cleaned_data.get('hash_tags')
if tags:
tags = split(str(tags))
if len(tags) > 5:
raise forms.ValiadationError('Maximum 5 tags are allowed')
return cleaned_data
You need to override clean method for your ModelForm.
Example:
class Post_Article(forms.ModelForm):
...
hash_tags = forms.CharField(max_length = 50,required = False)
...
class Meta:
model = PostsArticle
fields=("title", "abstract", "body", "image", "hash_tags",)
def clean(self):
cleaned_data=super(Post_Article, self).clean()
tags = cleaned_data.get("hash_tags")
if tags:
tags = split(str(tags))
if len(tags) > 5:
raise forms.ValidationError('Maximum 5 tags are allowed')
return cleaned_data
the clean funtion is not getting invoked
Django forms is
class Post_Article(forms.ModelForm):
title = forms.CharField(label = 'Title',max_length = 100)
abstract = forms.CharField(widget = forms.Textarea, max_length = 300)
body = forms.CharField(widget = forms.Textarea)
image = forms.ImageField(required = False)
hash_tags = forms.CharField(max_length = 50,required = False)
class Meta:
model = PostsArticle
fields=("title", "abstract", "body", "image", "hash_tags")
def clean(self):
print(hello)
cleaned_data=super(Post_Article, self).clean()
tags = cleaned_data.get("hash_tags")
if tags:
tags = split(str(tags))
if len(tags) > 5:
raise forms.ValidationError('Maximum 5 tags are allowed')
return cleaned_data
the clean funtion is not getting invoked
the formview for the same is
class PostCreateView(LoginRequiredMixin,FormView):
form_class = Post_Article
template_name= 'post/post.html'
success_url = '/'
def form_valid(self, form):
form.instance.user = self.request.user
print(form.instance.user)
return super().form_valid(form)
the formview is in the views.py

IntegrityError error while saving value of to foreign key in django

Hey folks i am getting integrity error while saving my views .Please tell me what i am doing wrong
Here is my django model
class Ruleinfo(models.Model):
rule = models.IntegerField(null=False)
From = models.IPAddressField(null=True)
to = models.IPAddressField(null=True)
priority = models.ForeignKey('Priority',related_name='pri_no')
cisp =models.ForeignKey('Priority',related_name = 'CISP_no')
def __unicode__(self):
return u'%s' %(self.rule)
class Priority(models.Model):
pri = models.IntegerField(null = True)
Ruleno = models.ForeignKey('Ruleinfo',related_name = 'ruleno_no')
CISP = models.IntegerField(null = True)
def __unicode__(self):
return u'%s ' % (self.priority)
My model form is looking like .
class RuleInfoForm(ModelForm):
class Meta:
model = Ruleinfo
fields = ("rule","From","to")
here is my views.py
def multiwanrule_info(request):
data = {}
no_of_isp = MultiWAN.objects.all()
try:
form = RuleInfoForm(request.POST)
except:
pass
print "----------------------------printing form"
print form
if form.is_valid():
rl_frm = form.save(commit=False)
get_priorities = request.POST.getlist('priority')
get_cisp_info = request.POST.getlist('cisp')
rule_object = Ruleinfo()
for get_pri,get_ci in zip(get_priorities,get_cisp_info,):
pri_object = Priority.objects.get_or_create(Ruleno = rule_object)
pri_object.pri = get_pri
pri_object.CISP = get_ci
rl_frm.save()
else:
form = RuleInfoForm()
data['form'] = form
data['number_of_isp'] = no_of_isp
return render_to_response('networking.html',data)
I am getting the above error along this
networking_priority.Ruleno_id may not be NULL
help me out so that i could get back on track .
rule_object = Ruleinfo()
This just instantiates a new model object. It is not saved or assigned values. Since it is not saved it does not have an id value.
assigning your rule_object values: rule, from, to, priority, and cisp values, should fix your problem.

Creating different completion paths using form wizard - Django

I was following the tutorial online, but I am stuck when trying to conditionally show steps in my form wizard.
views.py
def silver_ad_selected(wizard):
cleaned_data = wizard.get_cleaned_data_for_step('0') or {}
return cleaned_data.get('ad_type') == '2'
def platinum_ad_selected(wizard):
cleaned_data = wizard.get_cleaned_data_for_step('0') or {}
return cleaned_data.get('ad_type') == '3'
class AddWizard(SessionWizardView):
def done(self, form_list, **kwargs):
return render_to_response('business/done.html', {
'form_data': [form.cleaned_data for form in form_list],
})
urls.py:
add_forms = [AddForm1, AddForm2, AddForm3]
urlpatterns = patterns('listings.views',
url(r'^addWizard/$', AddWizard.as_view(add_forms,
condition_dict = {
'2': silver_ad_selected or premium_ad_selected
})),
.......
forms.py
class AddForm1(forms.Form):
TYPE_CHOICES = (
('1','Basic'),
('2','Silver'),
('3','Platinum')
)
ad_type = forms.ChoiceField(choices=TYPE_CHOICES, widget=forms.RadioSelect)
class AddForm2(forms.Form):
category = forms.ModelChoiceField(queryset = Category.objects.all())
city = forms.ModelChoiceField(queryset = City.objects.all())
name = forms.CharField(max_length = 200)
address = forms.CharField(max_length = 200)
slogan = forms.CharField(max_length=140)
phone = forms.CharField(max_length=10)
website = forms.URLField()
email = forms.EmailField()
class AddForm3(AddForm2):
twitter = forms.CharField(max_length=100)
facebook = forms.URLField()
description = forms.CharField(widget=forms.Textarea)
Basically, I only want to show the last step if the user chooses either the "Silver" option or the "Platinum" option, which is selected in step 1. Right now, no matter what I choose, only the first two steps/forms are shown.
I think that my silver_ad_selected and platinum_ad_selected methods might be the problem, but I am not sure.
Thanks
Try changing your urls.py:
add_forms = [AddForm1, AddForm2, AddForm3]
urlpatterns = patterns('listings.views',
url(r'^addWizard/$', AddWizard.as_view(add_forms,
condition_dict = {
'2': lambda wizard: wizard.silver_ad_selected() or wizard.premium_ad_selected()
})),

inlineformset_factory composed of ModelForm

Is it possible for an inlineformset_factory to take in a ModelForm as well as a model. When I try to run this I get an error message 'NoneType' object is not iterable.
Please help, I've spent an entire day trying to figure this out. Thanks.
Code:
Model.py
class FilterForm(ModelForm):
firstFilter = forms.BooleanField(label='First Filter', initial=False, required=False)
class Meta:
model = Filter
exclude = ('order')
class Controller(models.Model):
protocol = models.CharField('Protocol',max_length=64, choices=PROTOCOLS, default='http')
server = models.CharField('Server', max_length=64, choices=SERVERS, default='127.0.0.1')
name = models.CharField('Name', max_length=64)
def __unicode__(self):
return self.protocol + '://' + self.server + '/' + self.name
view.py
def controller_details(request, object_id):
controller = Controller.objects.get(pk=object_id)
controllerURI = controller.protocol + '://' + controller.server + '/' + controller.name
FilterFormSet = inlineformset_factory(Controller, FilterForm, extra=5)
if request.method == 'POST':
formset = FilterFormSet(request.POST, request.FILES, instance=controller)
if formset.is_valid():
filters = []
# Save all the filters into a list
forms = formset.cleaned_data
for form in forms:
if form:
protocol = form['protocol']
server = form['server']
name = form['name']
targetURI = form['targetURI']
filterType = form['filterType']
firstFilter = form['firstFilter']
if firstFilter == True:
aFilter = Filter(controller=controller, protocol=protocol, server=server, name=name, targetURI=targetURI, filterType=filterType, order=0)
else:
aFilter = Filter(controller=controller, protocol=protocol, server=server, name=name, targetURI=targetURI, filterType=filterType, order=-1)
filters.append(aFilter)
# Find the first filter in the list of filters
for index, aFilter in enumerate(filters):
if aFilter.order == 0:
break
if filters[index].targetURI:
test = "yes"
else:
for aFilter in filters:
aFilter.save()
else:
formset = FilterFormSet(instance=controller)
return render_to_response('controller_details.html', {'formset':formset, 'controllerURI':controllerURI}, context_instance=RequestContext(request))
UPDATE: If you intended to create a FormSet with Controller and Filter models where Filter holds a FK to the Controller, you need:
FilterFormSet = inlineformset_factory(Controller, Filter, form=FilterForm)
Note that in your code above, you're only passing the the Controller model class, which caused some confusion.