I would like to return to a specific page after I edit a record using Django "UpdateView", however this page url needs an argument passed to it as well (see urls.py below). I am pretty sure I need to use "get_absolute_url", which works when I am just redirecting to an unfiltered page, but can't seem to get the syntax to redirect to a filtered page.
Models.py
class DefaultDMLSProcessParams(models.Model):
device = models.ForeignKey(get_user_model(),on_delete=models.CASCADE,)
customerTag = models.CharField(max_length=50,)
processNotes = models.TextField(max_length=300,blank=True,default = "")
def __str__(self):
return str(self.defaultParamDescrip)
def get_absolute_url(self):
#self.object.pk? pass this below somehow?
return reverse('Default_Listview',)
views.py
class defaultUpdateView(LoginRequiredMixin,UpdateView):
model = models.DefaultDMLSProcessParams
fields = ['processNotes','customerTag']
template_name = 'default_edit.html'
login_url = 'login'
urls.py
path('<int:device>', DefaultsListView.as_view(), name='Default_Listview'),
Specify the parameter by args argument of reverse() function
def get_absolute_url(self):
# self.object.pk? pass this below somehow?
return reverse('Default_Listview', args=[self.id, ])
You could find more example in the Official Django doc .
Related
I'm playing with DRF just for fun and I'm trying to get single record by its ID.
Here is my setup:
Django version 2.1.4
DjangoRestFramework 3.9.0
models.py
class BoardModel(models.Model):
board_title = models.CharField(
...
)
board_c_time = models.DateTimeField(
...
)
urls.py
urlpatterns = [
re_path(r'^get_board(?P<pk>\d*)$', views.GetBoard.as_view(), name="get-board"),
]
serializers.py
class GetBoardSerializer(serializers.ModelSerializer):
"""Board serializer."""
class Meta:
model = BoardModel
fields = ("id", "board_title", "board_c_time")
views.py
class GetBoard(APIView):
"""Get single board."""
def get_object(self, pk):
"""Search for the object."""
try:
return models.BoardModel.objects.get(pk=pk)
except models.BoardModel.DoesNotExist:
raise Http404
def get(self, request, pk, format=None):
"""GET method."""
pk = int(request.query_params.get('pk'))
obj = self.get_object(pk)
serializer = GetBoardSerializer(obj)
return Response(serializer.data)
Sending GET request to my_url.com/api/get_board?pk=123.
Positional argument 'pk' in the get method of GetBoard class should take the value from the pk parameter in url (eg pk='123') however it returns an empty string.
Because of that I had to access it through request.query_params.get('pk') but it looks weird to me.
Did I miss something?
How to get value from the URL parameter into positional argument in the get method mentioned above?
Thanks a lot in advance!
If you're going to send the parameter as a query param which are the params identified in a url after the ? character, then you'll need to access them via request.query_params. If you want to pass it through the url, then you should adjust your urls.py to:
urlpatterns = [
re_path(r'^get_board/(?P<pk>\d*)$', views.GetBoard.as_view(), name="get-board"),
]
Then your url should be: my_url.com/api/get_board/123
I have a Django generic List View that I want to filter based on the value entered into the URL.
For example, when someone enters mysite.com/defaults/41 I want the view to filter all of the values matching 41.
I have come accross a few ways of doing this with function based views, but not class based Django views.
I have tried:
views.py
class DefaultsListView(LoginRequiredMixin,ListView):
model = models.DefaultDMLSProcessParams
template_name = 'defaults_list.html'
login_url = 'login'
def get_queryset(self):
return models.DefaultDMLSProcessParams.objects.filter(device=self.kwargs[device])
urls.py
path('<int:device>', DefaultsListView.as_view(), name='Default_Listview'),
You are close, the self.kwargs is a dictionary that maps strings to the corresponding value extracted from the URL, so you need to use a string that contains 'device' here:
class DefaultsListView(LoginRequiredMixin,ListView):
model = models.DefaultDMLSProcessParams
template_name = 'defaults_list.html'
login_url = 'login'
def get_queryset(self):
return models.DefaultDMLSProcessParams.objects.filter(
device_id=self.kwargs['device']
)
It is probably better to use devide_id here, since then it is syntactically clear that we compare identifiers with identifiers.
It might also be more "idiomatic" to make a super() call, such that if you later add mixins, these can "pre-process" the get_queryset call:
class DefaultsListView(LoginRequiredMixin,ListView):
model = models.DefaultDMLSProcessParams
template_name = 'defaults_list.html'
login_url = 'login'
def get_queryset(self):
return super(DefaultsListView, self).get_queryset().filter(
device_id=self.kwargs['device']
)
I have urls that take a parameter called board_slug. Before getting the template the view will replace the slug if its name is wrong and redirect it. I have already made the code for fixing the slug but do not know how insert the fixed board_slug into the new url. This code is run across multiple views so it has to work with all the following kinds urls:
url(r'^boards/(?P<board_slug>[^/]+)/$', views.BoardView.as_view(), name='board'),
url(r'^/front-thing/boards/(?P<board_slug>[^/]+)/new/$', views.BoardView.as_view(), name='new_board'),
url(r'^boards/(?P<board_slug>[^/]+)/etc...$', views.BoardView.as_view(), name='anything_with_board'),
class BoardView(View):
template_name = 'forums/board.html'
def get(self, request, board_slug):
if wrong:
url = get_django_url
url.board_slug = 'new-slug'
return redirect(url)
else:
return template
i am new in django framework, in my current try, i have two models (Client and Facture). Facture is displayed as a TabularInline in client change view.
i want display a link for each inlined facture object to download the file. so i added a custom view that download the facture file, but dont know how to link to it
class Client(models.Model):
...
class Facture(models.Model):
client = models.ForeignKey(Client, on_delete=models.CASCADE)
numero = models.IntegerField(unique=True, default=rand_code)
...
and in the admin.py:
class FactureInline(admin.TabularInline):
model = Facture
extra = 0
readonly_fields = ('numero', 'dl_link')
def DLFacture(self, request, obj):
...
response.write(pdf)
return response
def get_urls(self):
urls = super(FactureAdmin, self).get_urls()
from django.conf.urls import url
download_url = [
url(r'^(?P<pk>\d+)/download/$', self.admin_site.admin_view(self.DLFacture), name="download"),
]
return download_url + urls
def dl_link(self, obj):
from django.core.urlresolvers import reverse
return reverse("admin:clients_facture_download", args=[obj.pk])
admin.site.register(Facture, FactureAdmin)
class ClientAdmin(admin.ModelAdmin):
inlines = [
FactureInline,
]
admin.site.register(Client, ClientAdmin)
i get the following error:
Reverse for 'clients_facture_download' with arguments '(1,)' and keyword arguments '{}' not found. 0 pattern(s) tried: []
all works fine when i change the reverse url to
reverse("admin:clients_facture_change", args=[obj.pk])
so any one could help me know how to reverse the download view and if i am doing thinks right ?
thanks for any help
Firstly, you are using name='download', but trying to reverse clients_facture_download.
I would try changing the url from
url(r'^(?P<pk>\d+)/download/$', self.admin_site.admin_view(self.DLFacture), name="download"),
to
url(r'^(?P<pk>\d+)/download/$', self.admin_site.admin_view(self.DLFacture), name="clients_fracture_download"),
Secondly, InlineModelAdmin does not have a get_urls method. You should move it to your ClientAdmin class.
I would think you need to reverse the order in the url:
url(r'^download/(?P<pk>\d+)$', self.admin_site.admin_view(self.DLFacture), name="download"),
]
What is wrong with my approach?
When I post new data, I want it to return back to the page with the input fileds empty. But it gives me this error
NoReverseMatch at /school/new-school/
Reverse for 'new-school' with arguments '()' and keyword arguments '{}' not found. 0 pattern(s) tried: []
This is my model. Please note, reverse_lazy was imported
class SchoolList(models.Model):
name = models.CharField(max_length=15, null=False)
def __str__(self):
return '%s' % (self.name)
def get_absolute_url(self):
return reverse_lazy('new-school')
This is my url.py
url(r'^school-list/$', SchoolListtView.as_view(), name='school-list'),
url(r'^new-school/$', CreateSchoolListView.as_view(), name='new-school'),
url(r'^school(?P<pk>\d+)/update/$', SchoolListUpdate.as_view(), name='update-school')
This is my view for create.
class CreateSchoolListView(CreateView):
template_name = 'school\create_form.html'
model = SchoolList
fields = ['name']
This is how I specified the urls in the template.
Create New School
View all Schools
When the page is displayed, I can click the links and it will go to the correct pages. But when I post a data, the it throws the above error. I have been on this for hours and read many of the answers online. It seems mine is a unique case.
Try adding namespace to get_absolute_url().
def get_absolute_url(self):
return reverse_lazy('school:new-school')
Make sure you import your app's urls in your project's urls with namespace like:
url(r'^school/', include('school.urls', namespace="school"))
to use namespace in your templates like this:{% url 'school:new-school' %}
Or remove namespace:
url(r'^school/', include('school.urls'))
to use url without namespace in template:{% url 'new-school' %}
Using get_absolute_url would be a bad approach in this case, since it's an instance method, designed to get url for single model instance.
If you want to add method to model, you should use something like this:
#classmethod
def get_create_url(cls):
return reverse_lazy('school:new-school')