python code for django view - python

MODEL:
class Pathology(models.Model):
pathology = models.CharField(max_length=100)
class Publication(models.Model):
pubtitle = models.TextField()
class Pathpubcombo(models.Model):
pathology = models.ForeignKey(Pathology)
publication = models.ForeignKey(Publication)
List of pathology sent to HTML template as drop down menu
VIEW:
def search(request):
pathology_list = Pathology.objects.select_related().order_by('pathology')
User selects one pathology name from drop down menu and id retrieved by
VIEW:
def pathology(request):
pathology_id = request.POST['pathology_id']
p = get_object_or_404(Pathology, pk=pathology_id)
Where I'm stuck. I need the python/django syntax to write the following:
The pathology_id must now retrieve the publication_id from the table Pathpubcombo (the intermediary manytomany table). Once the publication_id is retrieved then it must be used to retrieve all the attributes from the publication table and those attributes are sent to another html template for display to the user.

you should be using many-to-many relations as described here:
http://www.djangoproject.com/documentation/models/many_to_many/
Like:
class Pathology(models.Model):
pathology = models.CharField(max_length=100)
publications = models.ManyToManyField(Publication)
class Publication(models.Model):
pubtitle = models.TextField()
Then
def pathology(request):
pathology_id = request.POST['pathology_id']
p = get_object_or_404(Pathology, pk=pathology_id)
publications = p.publications.all()
return render_to_response('my_template.html',
{'publications':publications},
context_instance=RequestContext(request))
Hope this works, haven't tested it, but you get the idea.
edit:
You can also use select_related() if there is no possibility to rename tables and use django's buildin support.
http://docs.djangoproject.com/en/dev/ref/models/querysets/#id4

Related

Django modelformset_factory: One more Form shown than there should actually be

I have the following model:
class Portfolio(models.Model):
id = models.AutoField(primary_key=True)
member = models.ForeignKey(Member, on_delete=models.CASCADE)
For that I made the ModelForm:
class PortfolioForm(forms.ModelForm):
class Meta:
model = Portfolio
exclude = ['id']
I need many of those in one template so I am creating them in the Following way in my view
def portfolio_form(request, pk):
...
PortfolioFormSet = modelformset_factory(Portfolio, form=PortfolioForm)
formset = PortfolioFormSet(queryset=Portfolio.objects.filter(pk__in=list_of_ids))
finally in the html I have this:
everything is working fine except that one more is shown in HTML than there actually are. I have verified them in the shell. There are 3 but 4 are shown.
I am displaying them in the table. I am positive that it is not the template.
By default, modelformset_factory uses extra=1. Set it to zero if you don't want any extra forms.
PortfolioFormSet = modelformset_factory(Portfolio, form=PortfolioForm, extra=0)

django-taggit obtain tags string from form

I trying to use django-taggit as a tag model.
model.py
class Product(models.Model):
product_no = models.IntegerField(primary_key=True)
...
tags = TaggableManager(blank=True)
views.py
def action(request):
product = Product()
user = User.objects.get(id=request.user.id)
product.seller_username = user
...
product.save()
tag_list = taggit.utils._parse_tags(request.POST['tags'])
product.tags.add(*tag_list)
When I call method product.tags.add(), I'm getting an error say
Product objects need to have a primary key value before you can access
their tags
Many solutions I find inform me to put product.save() before product.tags.add() to make pk available before access many-to-many field.
I've try it and still the error.
Note: the save() method work properly. It create new object in Product list and can be see in admin interface.
It seem that I have to change
product_no = models.IntegerField(primary_key=True)
to
product_no = models.AutoField(primary_key=True)
and it's fixed.

Listing foreign keys related to a proxy model in django admin

My models.py looks like this :
class Author(models.Model):
name = models.CharField()
class DraftBooks(models.Model):
title = models.CharField()
author = models.ForeignKey(Author)
status_choices = ((1,Draft),(2,Published))
status = models.SmallIntegerField(choices=status_choices)
class PubBooks(DraftBooks):
class meta:
proxy = True
verbose name = 'Published Books'
I am using a proxy model since I want a different change list view for books in draft state and books which have been published.To achieve this,my admin.py looks like this :
class AuthorAdmin(admin.ModelAdmin):
pass
admin.site.register(Author, AuthorAdmin)
class DraftBooksAdmin(admin.ModelAdmin):
list_display = ('title','author','status')
def queryset(self):
return DraftBooks.objects.filter(status='1')
admin.site.register(DraftBooks, DraftBooksAdmin)
class PubBooksAdmin(admin.ModelAdmin):
list_display = ('title','author','status')
def queryset(self):
return PubBooks.objects.filter(status='2')
admin.site.register(PubBooks, PubBooksAdmin)
This setup works perfectly fine.In my admin,now I have 3 change list views,one which shows a list of all authors,one which shows book which are in a draft state and finally one which shows the list of books which are in a published state.
I now need to add a hyperlink to every item (Author) in the authors' list overview that links to a view showing all books of the specific authors.For Example:
J.K. Rowling (books)
J.R.R. Tolkien (books)
where books is a hyperlink to a site showing all books of a particular author.
Now I am completely clueless as to how to do this.Django Xadmin has a plugin which provides just this feature.This Stackoverflow question also provides answer to this problem.But the problem is that they do not work in proxy models with the custom filters that I have.When I try to get the list of books by an author,I get only the books which are in Draft state.I would ideally want all the books,Draft and Published by an author.How do i achieve this ?

how to display many error django

i have following models
class tags(models.Model):
tag = models.CharField(max_length=15) # Tag name
tagDescription = models.TextField() # Tag Description
tagSlug = models.TextField() # Extra info can be added to the existing tag using this field
class stores(models.Model):
storeName = models.CharField(max_length=15) # Store Name
storeDescription = models.TextField() # Store Description
storeURL = models.URLField() # Store URL
storePopularityNumber = models.IntegerField(max_length=1) # Store Popularity Number
storeImage = models.ImageField(upload_to=storeImageDir) # Store Image
storeSlug = models.TextField() # This is the text you see in the URL
createdAt = models.DateTimeField() # Time at which store is created
updatedAt = models.DateTimeField() # Time at which store is updated
storeTags = models.ManyToManyField(tags)
class tagsAdmin(admin.ModelAdmin):
list_display = ('tag', 'tagDescription', 'tagSlug')
class storesAdmin(admin.ModelAdmin):
list_display = ('storeName','storeDescription','storeURL',
'storePopularityNumber','storeImage',
'storeSlug','createdAt','createdAt','storeTags'
)
admin.site.register(tags,tagsAdmin)
admin.site.register(stores,storesAdmin)
Whenever I am trying to run command : python manage.py syncdb
I got the error: django.core.exceptions.ImproperlyConfigured: 'storesAdmin.list_display[8]', 'storeTags' is a ManyToManyField which is not supported.
I don't understand what I am doing wrong here. I want to simply display all the models in the django admin site.
You can't reference a Many2ManyField like that, you have to use a method instead in the stores class that looks like this
def get_tags():
return self.storeTags.all()
and reference that in your list_display(...'get_tags')
This is done because the M2M field would result in lots of SQL queries that would slow the entire thing down so therefore the choice would have to come from the developer and not from the framework.
Please check:
ModelAdmin.list_display
"ManyToManyField fields aren’t supported, because that would entail executing a separate SQL statement for each row in the table. If you want to do this nonetheless, give your model a custom method, and add that method’s name to list_display. (See below for more on custom methods in list_display.)"
You can use a custom method to show values of ManyToManyField or simply remove storeTags from list_display

Django Form based on multiple models

If I have two models in Django application like this:
class Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
author = models.ForeignKey(Author)
title = models.CharField(max_length=100)
How can I create a single form that allows you add both an Author and a Book simultaneously. If the author exists in the system, I could simply display the book Form and link that to the author but it is very often that I need to allow my users to create the book and the author simultaneously.
How can I do this?
Thanks.
You can write a custom form, which will check if the author exists in the system use existing, if no, create new with provided name.
class CustomForm(forms.ModelForm):
author = forms.CharField()
def save(self, commit=True):
author, created = Author.objects.get_or_create(name=self.cleaned_data['author'])
instance = super(CustomForm,self).save(commit=commit)
instance.author = author
if commit:
instance.save()
return instance
class Meta:
model=Book
Not sure this code is working, but I suppose it can explain my idea.
You can create a view that handles multiple forms - see http://collingrady.wordpress.com/2008/02/18/editing-multiple-objects-in-django-with-newforms/ for an excellent example.
You'd have to ensure that the rendering of the form objects are done in the template with only one tag and one submit button.

Categories

Resources