Showing posts with label django-admin. Show all posts
Showing posts with label django-admin. Show all posts

Tuesday, September 4, 2018

Django: Hyperlink from Admin of Model to documentation

Leave a Comment

I have an application which uses the django admin interface extensively.

Some things in the admin GUI need explanations (domain/model specific docs).

We use sphinx and screenshots do explain details.

Is there a generic/automated way to create hyperlinks from the django admin interface of a model instance to the matching part in the docs?

I know that I could alter the admin templates of the models, but somehow I guess someone has a better idea how to solve this in a more professional way.

In my case the docs get hosted on the same server. AFAIK this is needed if you have the big dream, that there are links from the docs into the django application, too (but this is a different question).

What do I mean with "matching part in the docs"?

Imagine I have a model called "Foo".

And I have docs for the model (including images).

Now I would like to have a hyperlink from the admin page of the model to the docs for the model "Foo".

I think this is a very general issue. I think it is a pity that neither the framework nor a third party app help to write integrated docs.

3 Answers

Answers 1

This is the method that I use to create links in the admin site for a particular model.

class YourModelAdmin(admin.ModelAdmin):      def link_to_doc(self,obj):         link = 'https://www.stackoverflow.com'         return u'<a href="%s">%s</a>' % (link, "Link Name")      link_to_doc.allow_tags = True     link_to_doc.short_description = "Link Description for admin"      fields = (          'your_model_fields',          'link_to_doc'                )      readonly_fields = (          'your_model_readonly_fields',          'link_to_doc'                )   admin.site.register(YourModel, YourModelAdmin) 

Answers 2

This problem is specific and there is, as far as I know, very probably no out-of-the-box solution provided by Django.

However, as the requirement is to provide a link (URL) in the model admin, this could be easily accomplished using a virtual property in the model class.

We have a model Foo:

class Foo(models.Model):     bar = models.CharField(max_length=255)     baz = models.IntegerField() 

and model admin FooAdmin:

class FooAdmin(admin.ModelAdmin):     list_display = ('bar', 'baz')     fields = ('bar', 'baz') 

Now we want to provide a link to the documentation from the admin. Assuming that the documentation is automatically generated from the .rst files and followes a generic URL pattern, the docs could be available under a link like this:

http://localhost:8000/docs/foo/ 

Eventually the URL is defined in the urls.py something like this (pseudocode):

url(r'docs/(?P<model>\w+)/$', ViewClass.as_view(), name='docs') 

With these assumptions in mind we add the following things to the model class:

from django.db import models from django.utils.html import format_html from django.urls import reverse  class Foo(models.Model):     bar = models.CharField(max_length=255)     baz = models.IntegerField()      @property     def docurl(self):         url = reverse('docs')         return format_url(             '<a href="{url}">{model}</a>',             url=url,             model=self._meta.model_name         ) 

In the model admin we can use the property docurl as a read-only field:

class FooAdmin(admin.ModelAdmin):     list_display = ('bar', 'baz')     fields = ('bar', 'baz', 'docurl')     readonly_fields = ('docurl',) 

Because the property docurl will be used in all models, it is better to create a base model class for the project, create the property there, and let all other model classes inherit from that class.

Your actual case probably differs from this example, but the basic idea is to retrieve/generate the doc url in a model property and then use the property as a read-only field in the model admin.

The advantage over the other solution, that proposes generating the url directly in the model admin, is putting the business logic into the model. In this way the docurl can be used in many different places.

Answers 3

Don't know what to tell you, but how about you work with the included batteries:

Django’s admindocs app pulls documentation from the docstrings of models, views, template tags, and template filters for any app in INSTALLED_APPS and makes that documentation available from the Django admin.

Since your files are in .rst and not docstrings using sphinx-autodoc (linked for consideration) you can still use this mechanism, by providing a little help string as the class documentation, which then links to the more elaborate docs:

class Joy(models.Model):     """     The purpose of this model is to provide you with daily joy.     How to achieve this is  outlined in the     `documentation <https://docs.example.com/models/Joy>`_.     """ 
Read More

Friday, July 13, 2018

Can't log in super users created on the django admin backend

Leave a Comment

I'm trying to create superusers on the django admin backend, but somehow I can't get them to log in. Here's my user class,

class User(AbstractBaseUser, PermissionsMixin):     email = models.EmailField(unique=True, max_length=255)     mobile = PhoneNumberField(null=True)     username = models.CharField(null=False, unique=True, max_length=255)     full_name = models.CharField(max_length=255, blank=True, null=True)     is_staff = models.BooleanField(default=False)     is_superuser = models.BooleanField(default=False)     is_active = models.BooleanField(default=False)       USERNAME_FIELD = 'email'     REQUIRED_FIELDS = ['username']     objects = UserManager() 

Here's the UserManager function to create super user,

class UserManager(BaseUserManager):      def create_user(self, email, mobile=None, username=None, full_name=None, gender=None, birthday=None, password=None,                     is_staff=False,                     is_superuser=False, is_active=False, is_mobile_verified=False, is_bot=False, is_online=False,                     is_logged_in=True):         if not email:             raise ValueError("Can't create User without a mobile number!")         if not password:             raise ValueError("Can't create User without a password!")         user = self.model(             email=self.normalize_email(email),             mobile=mobile,             username=username,             full_name=full_name,             gender=gender,             birthday=birthday,             is_staff=is_staff,             is_superuser=is_superuser,             is_active=is_active,           )         user.set_password(password)         return user      def create_superuser(self, email, username, password=None):         user = self.create_user(             email,             username=username,             password=password,             is_staff=True,             is_superuser=True,             is_active=True,         )         user.save(self._db)         return user      @property     def is_superuser(self):         return self.is_superuser      @property     def is_staff(self):         return self.is_staff      @property     def is_active(self):         return self.is_active      @property     def is_mobile_verified(self):         return self.is_mobile_verified      def has_perm(self, perm, obj=None):         return self.is_staff or self.is_superuser      def has_module_perms(self, app_label):         return self.is_staff or self.is_superuser       @is_staff.setter     def is_staff(self, value):         self._is_staff = value      @is_superuser.setter     def is_superuser(self, value):         self._is_superuser = value      @is_active.setter     def is_active(self, value):         self._is_active = value 

Here's the relevant backend settings.

OAUTH2_PROVIDER = {     # this is the list of available scopes     'ACCESS_TOKEN_EXPIRE_SECONDS': 60 * 60 * 24,     'SCOPES': {'read': 'Read scope', 'write': 'Write scope', 'groups': 'Access to your groups'},     'OAUTH2_BACKEND_CLASS': 'oauth2_provider.oauth2_backends.JSONOAuthLibCore', }  AUTHENTICATION_BACKENDS = (         'django.contrib.auth.backends.ModelBackend', )  # REST Framework REST_FRAMEWORK = {     'DEFAULT_AUTHENTICATION_CLASSES': (         'oauth2_provider.contrib.rest_framework.OAuth2Authentication',     ),     'DEFAULT_PERMISSION_CLASSES': (         'rest_framework.permissions.IsAuthenticated',     ), } 

I'm checking the is_staff and is_superuser to true on the creation form, still nothing. The created super user can't log in on the admin backend. What am I doing wrong here.

2 Answers

Answers 1

First, you are using custom user model. In your settings file, do you tell django to use your model instead of default auth.models.User ?

Second,

you are calling self.create_user inside your create_superuser function.

Do you override the create_user function as well ?

If yes, please provide the implementation.

Update

You dont need to change implementation user mansger's functions as you did. IF you look at implementation of UserManger in django.auth.models. You can take inspiration from there and you avoid making a mistake - for example: you dont save model when you create standard user as you dont call save method.

I suggest to change your UserManager like this:

class UserManager(BaseUserManager):      use_in_migrations = True      def _create_user(self, email, password,  **extra_fields):          if not email:             raise ValueError('The given email must be set')         email = self.normalize_email(email)         user = self.model(email=email, **extra_fields)         user.set_password(password)         user.save(using=self._db)         return user      def create_user(self, email, password=None, **extra_fields):          extra_fields.setdefault('is_staff', False)         extra_fields.setdefault('is_superuser', False)         extra_fields.setdefault('is_active', False)          return self._create_user(email, password, **extra_fields)      def create_superuser(self, email, password, **extra_fields):          extra_fields.setdefault('is_staff', True)         extra_fields.setdefault('is_superuser', True)          if extra_fields.get('is_staff') is not True:             raise ValueError('Superuser must have is_staff=True.')         if extra_fields.get('is_superuser') is not True:             raise ValueError('Superuser must have is_superuser=True.')                return self._create_user(email, password, **extra_fields) 

Answers 2

I created a new project with your code and I cannot reproduce your problem. Everything works fine on my side. However, I do notice a few things about your code:

First, in your settings.py, make sure you have set AUTH_USER_MODEL to your_app.User.

Second, in your UserManager class, I found things this:

@property def is_staff(self):     return self.is_staff 

This looks like an error to me, as it would produces infinite recursions. I guess in your case, there is a catch-all clause in django's code so the RecursionError is silenced. This may very likely be the problem.

Read More

Monday, December 25, 2017

How to check django staff user first time login in admin panel?

Leave a Comment

I am working on a django project and I am using the default auth app for authentication.
I know that there is a last_login field in user model which stores the user's last login time.

When a staff user logs in first time into the admin panel, I want to check if last_login field is none & redirect him to the change password page.

Where should I put this check?


What I have tried so far:

I have tried to use a custom login form and override the default confirm_login_allowed method on it, but it seems like I can only raise a validation error to block login attempt using these.

I also tried using django.contrib.auth.signals.user_logged_in Signal but that also does not allow me to return a redirect response when last_login is None.

I want to know how I can return a redirect response after the user has been authenticated.

3 Answers

Answers 1

Customise Django admin using AdminSite and use login_form attribute to give the custom login form for the Admin login page.

admin.py

class MyAdminSite(AdminSite):     login_form = CustomAdminLoginForm  admin_site = MyAdminSite(name='myadmin') admin_site.register(User) admin_site.register(Group 

urls.py

When overriding the Admin we have to get rid of Django default admin

from app.admin import admin_site  url(r'^admin/', admin_site.urls) 

forms.py

AuthenticationForm have the confirm_login_allowed method use this to grant permission to login in or not login in.

class CustomAdminLoginForm(AuthenticationForm):     def confirm_login_allowed(self, user):         if user.last_login:             raise ValidationError(mark_safe('Hey first time user please reset your password here... <a href="/test">test</a>'), code='inactive') 

Note: There is lot of edge cases you have to consider for this approach.

  1. What if user not set the password in the first time and how you're going to handle second attempt..? This time last_long not None. Although date_joined comes rescue. last_login == date_joined
  2. But What if the user not set the password in first day and comes next day ?

Edit:

You can use signal to check the logged in user and apply the config_login_allowed logic here...?

from django.contrib.auth.signals import user_logged_in   def change_password_first_time(sender, user, request, **kwargs):     # Your business logic here...  user_logged_in.connect(change_password_first_time) 

Answers 2

I believe that you can subclass the AdminSite and use the user_passes_test decorator UserPassesTestMixin to enforce the test on the login view.

[ - Create your test:

    def last_login_check(user):         return user.last_login is not None 

I would suggest making the test more robust because this one seems a bit flimsy (but answers your initial request)... ]

UserPassesTestMixin inherits from AccessMixin which has a login_url attribute that allows us to set the redirect url.

Override AdminSite:

from django.contrib.admin import AdminSite from django.contrib.auth.decorators import user_passes_test  class MyAdminSite(UserPassesTestMixin, AdminSite):     login_url='/your/redirect/url/'      def test_func(self):         return self.request.user.last_login is not None 

You don't need to add anything else.

To use MyAdminSite (documentation link):

admin_site = MyAdminSite(name='my_project_admin')  admin_site.register(MyModel)... 

Answers 3

Django admin is not that configurable. You should hook into its internal views. Login/logout views are inside Django AdminSite class (the one you usually access by admin.site). My implementation is a bit hacky but small:

Paste at the top of urls.py

from django.contrib import admin from django.contrib.admin import AdminSite from django.contrib.auth.models import User from django.core.urlresolvers import reverse from django.http import HttpResponseRedirect  class MyAdminSite(AdminSite):     def login(self, request, extra_context=None):         new_user = False         user = None          username = request.POST.get('username')  # Hack to find user before its last_login set to now.         if username:             user = User.objects.filter(username=username).first()             if user:                 new_user = user.last_login is None          r = super(MyAdminSite, self).login(request, extra_context)          if new_user and request.user == user and isinstance(r, HttpResponseRedirect):  # Successful logins will result in a redirect.             return HttpResponseRedirect(reverse('admin:password_change'))         return r  admin.site = MyAdminSite() 

If you want a cleaner solution I suggest to use a boolean inside user model instead of relying on last_login so you could just check request.user instead of my hack into request.POST.

You could read AdminSite.login and django.contrib.auth.views.login to see what is actually happening inside Django.

Read More

Monday, November 20, 2017

Crash validating related model created using inline admin

Leave a Comment

I'm creating a one-to-one model to extend the functionality of an existing model type, but I want it to only allow creating the extension model in certain cases. I enforce this constraint by throwing a ValidationError in the full_clean on the new Extended model. This works great when I create Extended models using Extended's ModelAdmin directly (it highlights the a field if it's the wrong type), but when I use StackedInline to inline Extended creation in As ModelAdmin, and A is the wrong type, the form fails to catch the ValidationError and I get the message A server error occurred. Please contact the administrator.

This is how I have the models set up:

# models.py from django.db import models  class A(models.Model):     type = models.IntegerField(...)  class Extended(models.Model)     a = models.OneToOneField(A)      def clean_fields(self, **kwargs):         if self.a.type != 3:             raise ValidationError({'a': ["a must be of type 3"]})         super(Extended, self).clean_fields(**kwargs)      def save(self, *args, **kwargs):         self.full_clean()         super(Extended, self).save(*args, **kwargs)  # admin.py from django.contrib import admin  class ExtendedInline(admin.StackedInline):     model = Extended  @admin.register(A) class AAdmin(admin.ModelAdmin):     inlines = (ExtendedInline,) 

The full traceback:

Traceback (most recent call last):   File "/usr/local/lib/python2.7/wsgiref/handlers.py", line 85, in run     self.result = application(self.environ, self.start_response)   File "/usr/local/lib/python2.7/site-packages/django/contrib/staticfiles/handlers.py", line 63, in __call__     return self.application(environ, start_response)   File "/usr/local/lib/python2.7/site-packages/whitenoise/base.py", line 66, in __call__     return self.application(environ, start_response)   File "/usr/local/lib/python2.7/site-packages/django/core/handlers/wsgi.py", line 189, in __call__     response = self.get_response(request)   File "/usr/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 218, in get_response     response = self.handle_uncaught_exception(request, resolver, sys.exc_info())   File "/usr/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 132, in get_response     response = wrapped_callback(request, *callback_args, **callback_kwargs)   File "/usr/local/lib/python2.7/site-packages/django/contrib/admin/options.py", line 618, in wrapper     return self.admin_site.admin_view(view)(*args, **kwargs)   File "/usr/local/lib/python2.7/site-packages/django/utils/decorators.py", line 110, in _wrapped_view     response = view_func(request, *args, **kwargs)   File "/usr/local/lib/python2.7/site-packages/django/views/decorators/cache.py", line 57, in _wrapped_view_func     response = view_func(request, *args, **kwargs)   File "/usr/local/lib/python2.7/site-packages/django/contrib/admin/sites.py", line 233, in inner     return view(request, *args, **kwargs)   File "/usr/local/lib/python2.7/site-packages/django/contrib/admin/options.py", line 1521, in change_view     return self.changeform_view(request, object_id, form_url, extra_context)   File "/usr/local/lib/python2.7/site-packages/django/utils/decorators.py", line 34, in _wrapper     return bound_func(*args, **kwargs)   File "/usr/local/lib/python2.7/site-packages/django/utils/decorators.py", line 110, in _wrapped_view     response = view_func(request, *args, **kwargs)   File "/usr/local/lib/python2.7/site-packages/django/utils/decorators.py", line 30, in bound_func     return func.__get__(self, type(self))(*args2, **kwargs2)   File "/usr/local/lib/python2.7/site-packages/django/utils/decorators.py", line 145, in inner     return func(*args, **kwargs)   File "/usr/local/lib/python2.7/site-packages/django/contrib/admin/options.py", line 1470, in changeform_view     self.save_related(request, form, formsets, not add)   File "/usr/local/lib/python2.7/site-packages/django/contrib/admin/options.py", line 1104, in save_related     self.save_formset(request, form, formset, change=change)   File "/usr/local/lib/python2.7/site-packages/django/contrib/admin/options.py", line 1092, in save_formset     formset.save()   File "/usr/local/lib/python2.7/site-packages/django/forms/models.py", line 636, in save     return self.save_existing_objects(commit) + self.save_new_objects(commit)   File "/usr/local/lib/python2.7/site-packages/django/forms/models.py", line 767, in save_new_objects     self.new_objects.append(self.save_new(form, commit=commit))   File "/usr/local/lib/python2.7/site-packages/django/forms/models.py", line 900, in save_new     obj.save()   File "/code/app/models.py", line 162, in save     self.full_clean()   File "/usr/local/lib/python2.7/site-packages/django/db/models/base.py", line 1171, in full_clean     raise ValidationError(errors) ValidationError: {'a': [u'a must be of type 3']} 

I'm currently using Django version 1.8

2 Answers

Answers 1

Inline foreignkeys are excluded on the calls to full_clean() that happen in modelform validators, so your ValidationError is not being caught by the form's is_valid() call.

From django/forms/models.py:

def _post_clean(self):     opts = self._meta      exclude = self._get_validation_exclusions()      try:         self.instance = construct_instance(self, self.instance, opts.fields, exclude)     except ValidationError as e:         self._update_errors(e)      # Foreign Keys being used to represent inline relationships     # are excluded from basic field value validation. This is for two     # reasons: firstly, the value may not be supplied (#12507; the     # case of providing new values to the admin); secondly the     # object being referred to may not yet fully exist (#12749).     # However, these fields *must* be included in uniqueness checks,     # so this can't be part of _get_validation_exclusions().     for name, field in self.fields.items():         if isinstance(field, InlineForeignKeyField):             exclude.append(name)      try:         self.instance.full_clean(exclude=exclude, validate_unique=False)     except ValidationError as e:         self._update_errors(e)      # Validate uniqueness if needed.     if self._validate_unique:         self.validate_unique() 

They're being caught in save() instead (where you call full_clean without the exclusion), which is too late.

Move your validation to clean() instead:

def clean(self):     if self.a.type != 3:         raise ValidationError({'a': ["a must be of type 3"]}) 

Then there will be no need to call full_clean from your save method. This method is where any validation of this sort should go as per the docs.

Answers 2

Though not ideal, spinkus posted an answer that's also fixing my crash. It involves overriding the changeform_view method in AAdmin:

@admin.register(A) class AAdmin(admin.ModelAdmin):     inlines = (ExtendedInline,)      def changeform_view(self, request, object_id=None, form_url='', extra_context=None):         # Need to override to catch ValidationError in pre_save and save hooks.         try:             return super(AAdmin, self).changeform_view(request, object_id, form_url, extra_context)         except ValidationError as e:             self.message_user(request, '\n'.join(e.messages), level=messages.ERROR)             return HttpResponseRedirect(form_url) 

This causes AAdmin to show an error message at the top of the form instead of crashing. Unfortunately, it clears the user's other changes and doesn't do field-level highlighting.

Read More

Saturday, September 9, 2017

Add checkbox and delete actions to customized Django admin change_list

Leave a Comment

I've been customizing Django's change_list.html following this tutorial. My question concerns something that wasn't covered in that tutorial:

How to easily add the checkbox and the actions (delete selected items)?

I took a look in the templatetags of the admin section (mainly here, but I couldn't understand how to easily add the delete action to each item in a customized change_list.html template and what should be added to the ModelAdmin class).

Update:

Below is the custom change_list.html, I'm trying to add item checkboxes to:

{% extends "admin/change_list.html" %}  {% block content_title %}     <h1>Title</h1> {% endblock %}  {% block result_list %}     <div class="results">         <table id="result_list">             <thead>                 ...             </thead>              <tbody>                 {% for item in items %}                     <tr class="{% cycle 'row1' 'row2' %}">                         ...                     </tr>                 {% endfor %}             </tbody>         </table>     </div> {% endblock %} 

0 Answers

Read More

Monday, August 21, 2017

NoReverseMatch error when creating new users through admin

Leave a Comment

In my django app, I've created a custom User model which extends AbstractUser. I updated the AUTH_USER_MODEL and registered it under the admin like so

admin.site.register(MyUser, UserAdmin)

I ran the migrations and then went under my admin page and saw it listed under the app's models. But when I tried created a new user from that page, it gave me this error.

enter image description here

User class in models.py:

class MyUser(AbstractUser):     id = models.CharField(primary_key = True, unique = True, max_length = 50) 

Any ideas? Edit: updated to include main urls.py

from django.conf.urls import url, include from django.contrib import admin  urlpatterns = [     url(r'^admin/', include(admin.site.urls)),     url(r'^api/', include('api.urls')) ]       

Edit 2: updated to include stacktrace

Internal Server Error: /admin/api/myuser/add/ Traceback (most recent call last): File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/core/handlers/exception.py", line 41, in inner   response = get_response(request) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/core/handlers/base.py", line 187, in _get_response   response = self.process_exception_by_middleware(e, request) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/core/handlers/base.py", line 185, in _get_response   response = wrapped_callback(request, *callback_args, **callback_kwargs) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/contrib/admin/options.py", line 551, in wrapper   return self.admin_site.admin_view(view)(*args, **kwargs) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/utils/decorators.py", line 149, in _wrapped_view   response = view_func(request, *args, **kwargs) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/views/decorators/cache.py", line 57, in _wrapped_view_func   response = view_func(request, *args, **kwargs) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/contrib/admin/sites.py", line 224, in inner   return view(request, *args, **kwargs) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/utils/decorators.py", line 67, in _wrapper   return bound_func(*args, **kwargs) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/views/decorators/debug.py", line 76, in sensitive_post_parameters_wrapper return view(request, *args, **kwargs) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/utils/decorators.py", line 63, in bound_func   return func.__get__(self, type(self))(*args2, **kwargs2) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/utils/decorators.py", line 67, in _wrapper   return bound_func(*args, **kwargs) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/utils/decorators.py", line 149, in _wrapped_view   response = view_func(request, *args, **kwargs) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/utils/decorators.py", line 63, in bound_func   return func.__get__(self, type(self))(*args2, **kwargs2) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/contrib/auth/admin.py", line 103, in add_view   return self._add_view(request, form_url, extra_context) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/contrib/auth/admin.py", line 131, in _add_view extra_context) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/contrib/admin/options.py", line 1508, in add_view   return self.changeform_view(request, None, form_url, extra_context) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/utils/decorators.py", line 67, in _wrapper   return bound_func(*args, **kwargs) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/utils/decorators.py", line 149, in _wrapped_view   response = view_func(request, *args, **kwargs) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/utils/decorators.py", line 63, in bound_func   return func.__get__(self, type(self))(*args2, **kwargs2) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/contrib/admin/options.py", line 1408, in changeform_view   return self._changeform_view(request, object_id, form_url, extra_context) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/contrib/admin/options.py", line 1453, in _changeform_view   return self.response_add(request, new_object) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/contrib/auth/admin.py", line 211, in response_add post_url_continue) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/contrib/admin/options.py", line 1052, in response_add current_app=self.admin_site.name, File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/urls/base.py", line 91, in reverse return force_text(iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs))) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/urls/resolvers.py", line 497, in _reverse_with_prefix   raise NoReverseMatch(msg) django.urls.exceptions.NoReverseMatch: Reverse for 'api_myuser_change' with arguments '('',)' not found. 1 pattern(s) tried: ['admin/api/myuser/(.+)/change/$'] 

Edit 3: INSTALLED_APPS

INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'rest_framework', 'rest_framework.authtoken', 'api', 'django_jinja', ] 

3 Answers

Answers 1

You've replaced your primary key with a CharField but you're still using Django's UserAdmin ModelAdmin. Django's UserAdmin doesn't ask for the ID – it's defaulting to an empty string. (You can verify this by checking for the empty string in the arguments from the NoReverseMatch Exception.)

You need to create a ModelAdmin that allows you to specify the ID so it doesn't end up as an empty string. The following admin.py will allow you to specify the ID thus getting rid of your NoReverseMatch exception.

# -*- coding: utf-8 -*- from __future__ import unicode_literals  from django.contrib import admin from django.contrib.auth.admin import UserAdmin  from .models import MyUser  class MyUserAdmin(UserAdmin):     add_fieldsets = (         (None, {             'fields': ('id', 'username', 'password1', 'password2'),         }),     )  # Register your models here. admin.site.register(MyUser, MyUserAdmin) 

Answers 2

you'd have register your model in admin site

from django.contrib import admin  from django.contrib.auth.admin import UserAdmin from .models import User  admin.site.register(User, UserAdmin) 

also you must have your model with id with integer number

class MyUser(AbstractUser):      pass 

Answers 3

The error message shows the url as /myuser/add and your urls say it only have the /myuser/change/ defined. Define the /myuser/add class/function view or update the url to point to the add class/function view.

Read More

Tuesday, May 2, 2017

Django Admin escaping text

Leave a Comment

I recently upgraded Django from 1.3 to 1.8.18 and been having issues with links custom made to pre-fill forms in Django admin. For example, I have the following link:

/admin/miscellaneous/whatsnew/add/?title=...%20competition%20results%20uploaded&pub_date=21-04-2017&body=&link= 

When executed the pre-filled data in the form looks like: enter image description here

Where it should look like this:

enter image description here

When testing directly from the URL bar in Safari it changes to this after pressing enter:

https://flyball.org.au/admin/miscellaneous/whatsnew/add/?title=...%2520competition%2520results%2520uploaded&pub_date=21-04-2017&body=&link= 

models.py

class WhatsNew(models.Model):     title = models.CharField(max_length=100,help_text='Title, MAX 100 characters.')     body = models.TextField()     pub_date = models.DateField()     message_expiry = models.DateField(default=datetime.date.today() + relativedelta(years=1))     link = models.URLField(blank=True, null=True)      class Meta:         ordering = ['-pub_date']         verbose_name_plural = "Whats New?"      def __unicode__(self):         return self.title 

admin.py

import models from django.contrib import admin  class WhatsNewAdmin(admin.ModelAdmin):     list_display = ('title','pub_date','message_expiry','link','body')  admin.site.register(models.WhatsNew, WhatsNewAdmin) 

What can I do to resolve this?

2 Answers

Answers 1

So, I'm not sure how to do it on the ModelAdmin, but you can create custom setters on your model to handle this situation. Here's how I would go about escaping the URL encoded strings:

import urllib   class WhatsNew(models.Model):     # Field with custom setter     _title = models.CharField(max_length=100,                              help_text='Title, MAX 100 characters.',                              db_column='title')      body = models.TextField()     pub_date = models.DateField()     message_expiry = models.DateField(default=datetime.date.today() + relativedelta(years=1))     link = models.URLField(blank=True, null=True)      # Custom getter and setter     @property     def title(self):         return self._title      @title.setter     def title(self, value):         self._title = urllib.unquote(value)      class Meta:         ordering = ['-pub_date']         verbose_name_plural = "Whats New?"      def __unicode__(self):         return self._title 

Answers 2

Use + instead of %20 for space and it works.

Your link should be something like:

/admin/miscellaneous/whatsnew/add/?title=...+competition+results+uploaded&pub_date=21-04-2017&body=&link= 
Read More

Sunday, April 16, 2017

How to change User representation in Django Admin when used as Foreign Key?

Leave a Comment

I have a few models having User as Foreign Key. The User list is displaying the username, but I'd like to customize it. Do I have to extend the User model with a custom model and write my own __str__ function? Is there an easier way? I don't think you can use a callable for fieldset, right?

4 Answers

Answers 1

I think __unicode__() method is not the correct, you should use __str__() method.

For Python 2.x, __str__() method will return str(bytes) and __unicode__() method will return unicode (text).

The print statement and the str built-in call __str__() to determine the human-readable representation of an object. The unicode built-in calls __unicode__() if it exists, and otherwise falls back to __str__() and decodes the result with the system encoding. Conversely, the Model base class automatically derives __str__() from __unicode__() by encoding to UTF-8. read here complete

But in Python 3.x there is just __str__(), no __unicode__() method.

Django provides a simple way to define __str__() and __unicode__() methods that work on Python 2 and 3: you must define a __str__() method returning text and to apply the python_2_unicode_compatible() decorator.

On Python 3, the decorator is a no-op. On Python 2, it defines appropriate __unicode__() and __str__() methods (replacing the original __str__() method in the process).

Here is an example from django docs.

from django.utils.encoding import python_2_unicode_compatible  @python_2_unicode_compatible class MyClass(object):     def __str__(self):         return "Instance of my class" 

SOLUTION : Decorate in the same way, as done above for your Class and in models.py, add a method which will be get added to the User model.

from django.contrib.auth.models import User  def get_name(self):     return '{} {}'.format(self.first_name, self.last_name)  User.add_to_class("__str__", get_name) 

Answers 2

You can change the string representation of the Django default User by overriding the User __unicode__ method. Add the code below somewhere in your app, perhaps in models.py

def custom_user_display(self):     return self.email + ', ' self.first_name # write your representation here  User.add_to_class("__unicode__", custom_user_display) # override the __unicode__ method 

Answers 3

Assume you have a model like this

class UserProfile(models.Model):     user = models.OneToOneField(User, unique=True, verbose_name=_('user'), related_name='profile')     city = models.CharField(max_length=128, null=True, blank=True) 

And you want to show the user's email instead of username or userid in admin page, then you can do something like this

class UserProfileAdmin(admin.ModelAdmin):     list_display = ('get_user', 'city')      def get_user(self, obj):         return obj.user.email     get_user.short_description = 'User'     get_user.admin_order_field = 'user__id' 

Answers 4

ForeignKeys in Django forms are represented by ModelChoiceFields. The ModelChoiceField class has a label_from_instance method, which decides how to render the choice. So in order to change this representation in the Admin, you need to modify this form field.

Here is a simple example.

class MyModelAdmin(admin.ModelAdmin):     def formfield_for_foreignkey(self, db_field, request, **kwargs):         field = super(MyModelAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)         if db_field.name == "user":             field.label_from_instance = lambda u: "My Object #%i" % u.id         return field 
Read More

Friday, February 17, 2017

Malformed Packet: Django admin nested form can't submit, connection was reset

Leave a Comment

I have a django nested admin form and below code is my admin.py file content:

# -*- coding:utf-8 -*- from django.db.models import Q from django import forms  from django.contrib.auth.admin import UserAdmin as AuthUserAdmin from django.contrib import admin from django.contrib.auth.forms import UserCreationForm, UserChangeForm from django.contrib.auth.hashers import UNUSABLE_PASSWORD_PREFIX, identify_hasher from django.forms.utils import flatatt from django.utils.html import format_html from django.utils.safestring import mark_safe from django.utils.translation import ugettext as _, ugettext from django.contrib.auth.models import Group, Permission from nested_admin.nested import NestedStackedInline, NestedModelAdmin  from HomeMakers.apps.system.models import Dependant, Benefit, User, \     Unit, Stack, Parking from mtools.fields import UniqueValueWidget, PersianDateField   class DependantAdminForm(forms.ModelForm):     model = Dependant     birth_date = PersianDateField(label=u'تاریخ تولد')   class DependantAdmin(NestedStackedInline):     model = Dependant     form = DependantAdminForm      extra = 0     exclude = ['changed_status', 'new_obj']     can_delete = True   class BenefitSubAdmin(admin.TabularInline):     model = Benefit     extra = 1     min_num = 0      exclude = ['changed_status', 'new_obj']     can_delete = True   class NewUserAdminForm(UserCreationForm):     class Meta(UserCreationForm.Meta):         model = User      username = forms.RegexField(label=u"کد ملی", max_length=30, regex=r'^\d{8,10}$',                                 widget=UniqueValueWidget,                                 error_messages={'invalid': u"مقدار وارد شده قابل قبول نمیباشد."})     birth_date = PersianDateField(from_year=1290, to_year=1400, label=_('Birth Date'))     start_date = PersianDateField(from_year=1290, to_year=1400, label=u"تاریخ شروع به کار")      def clean_username(self):         # Since User.username is unique, this check is redundant,         # but it sets a nicer error message than the ORM. See #13147.         username = self.cleaned_data["username"]         if User.objects.filter(username=username).count() > 0:             raise forms.ValidationError(self.error_messages['duplicate_username'])         return username   class ReadOnlyPasswordHashWidget(forms.Widget):     def render(self, name, value, attrs):         encoded = value         final_attrs = self.build_attrs(attrs)          if not encoded or encoded.startswith(UNUSABLE_PASSWORD_PREFIX):             summary = mark_safe(u"<strong>%s</strong>" % _("No password set."))         else:             try:                 hasher = identify_hasher(encoded)             except ValueError:                 summary = mark_safe(u"<strong>%s</strong>" % _(                     "Invalid password format or unknown hashing algorithm."))             else:                 summary = u'''format_html_join('',                                            "<strong>{0}</strong>: {1} ",                                            ((ugettext(key), value)                                             for key, value in hasher.safe_summary(encoded).items())                                            )'''          return format_html(u"<div{0}>{1}</div>", flatatt(final_attrs), summary)   class ReadOnlyPasswordHashField(forms.Field):     widget = ReadOnlyPasswordHashWidget      def __init__(self, *args, **kwargs):         kwargs.setdefault("required", False)         super(ReadOnlyPasswordHashField, self).__init__(*args, **kwargs)      def bound_data(self, data, initial):         # Always return initial because the widget doesn't         # render an input field.         return initial      def _has_changed(self, initial, data):         return False   class EditUserAdminForm(UserChangeForm):     class Meta(UserChangeForm.Meta):         model = User      birth_date = PersianDateField(from_year=1290, to_year=1400, label=_('Birth Date'))     start_date = PersianDateField(from_year=1290, to_year=1400, label=u"تاریخ شروع به کار")     password = ReadOnlyPasswordHashField(label=_("Password"),         help_text=_("Raw passwords are not stored, so there is no way to see "                     "this user's password, but you can change the password "                     "using <a href=\"password/\">this form</a>."))      error_messages = {'duplicate_username': 'An user by this international code already exists.'}      def __init__(self, *args, **kwargs):         super(EditUserAdminForm, self).__init__(*args, **kwargs)         self.fields['username'] = forms.RegexField(label=u"کد ملی", max_length=30, regex=r'^\d{8,10}$',                                                    widget=UniqueValueWidget(),                                                    error_messages={'invalid': u"مقدار وارد شده قابل قبول نمیباشد."})         self.fields['username'].widget.attrs['value'] = self.instance.username      def clean_username(self):         # Since User.username is unique, this check is redundant,         # but it sets a nicer error message than the ORM. See #13147.         username = self.cleaned_data["username"]         if username != self.instance.username and User.objects.filter(username=username).count() > 0:             raise forms.ValidationError(self.error_messages['duplicate_username'])         return username   class UnitForm(forms.ModelForm):     model = Unit     installment_begin_date = PersianDateField(label=u'تاریخ شروع اقساط')   class StackSubAdmin(NestedStackedInline):     model = Stack     extra = 1   class ParkingSubAdmin(NestedStackedInline):     model = Parking     extra = 1   class UnitSubAdmin(NestedStackedInline):  #(admin.StackedInline):     model = Unit     form = UnitForm     extra = 0      inlines = [ParkingSubAdmin, StackSubAdmin]     exclude = ['sum_of_pays', 'parkings', 'warehouse']   class UserAdmin(AuthUserAdmin, NestedModelAdmin):     model = User     ordering = ['last_name']     list_per_page = 10     add_form = NewUserAdminForm     form = EditUserAdminForm     list_display = ['user_thumb', 'first_name', 'last_name']      list_filter = ['units__project', 'groups']      formfield_overrides = {         # models.DateField: {'widget': PersianDateWidget}     }      '''fields = (         'username', 'password', 'first_name', 'last_name', 'email',         'gender', 'birth_date', 'picture', 'certificate_no', 'birth_place', 'address', 'home_phone', 'work_phone',         'mobile', 'personnel_code', 'international_code', 'job_field', 'self_employed_job_name', 'employment_type',         'start_date', 'is_retired'     )'''      inlines = [DependantAdmin, UnitSubAdmin]  # & BenefitSubAdmin      def get_fieldsets(self, request, obj=None):         key_fields = {'fields': ('username', 'password1', 'password2')}         if obj is not None:             key_fields = {'fields': ('username', 'password')}          fieldsets = (             (None, key_fields),             (u'اطلاعات تکمیلی', {'fields': (                 'first_name', 'last_name', 'email',                 'gender', 'birth_date', 'academic_degree', 'picture', 'international_card_scaned_file',                 'certificate_scaned_file_page1', 'certificate_scaned_file_page2', 'academic_degree_scaned_file',                 'job_edict_document', 'certificate_no', 'birth_place', 'address', 'home_phone', 'work_phone',                 'mobile', 'personnel_code', 'job_field', 'self_employed_job_name', 'employment_type', 'start_date',                 'is_retired'                 )}              ),             (u'سطوح دسترسی', {'fields': ('is_active', 'is_staff', 'groups')})             # , 'user_permissions', 'is_superuser')}),             #  (u'تاریخ های مهم', {'fields': ('last_login', 'date_joined')})         )         if request.user.is_superuser:             fieldsets = (                 (None, key_fields),                 (u'اطلاعات تکمیلی', {'fields': (                     'first_name', 'last_name', 'email',                     'gender', 'birth_date', 'academic_degree', 'picture', 'international_card_scaned_file',                     'certificate_scaned_file_page1', 'certificate_scaned_file_page2', 'academic_degree_scaned_file',                     'job_edict_document', 'certificate_no', 'birth_place', 'address', 'home_phone', 'work_phone',                     'mobile', 'personnel_code', 'job_field', 'self_employed_job_name', 'employment_type', 'start_date',                     'is_retired'                     )}                  ),                 (u'سطوح دسترسی', {'fields': (                          'is_active',                          'is_staff',                          'is_superuser',                          'user_permissions',                          'groups'                     )                 })                 #  (u'تاریخ های مهم', {'fields': ('last_login', 'date_joined')})             )         return fieldsets      def get_queryset(self, request):         if request.user.is_superuser:             return User.objects.all()         return User.objects.filter(is_superuser=False)   class GroupAdmin(admin.ModelAdmin):     model = Group     filter_horizontal = ('permissions',)      def formfield_for_manytomany(self, db_field, request, **kwargs):         if db_field.name == "permissions" and not request.user.is_superuser:             kwargs["queryset"] = Permission.objects.exclude(                 Q(codename__startswith='add_') |                 Q(codename__startswith='change_') |                 Q(codename__startswith='delete_')             )         return super(GroupAdmin, self).formfield_for_manytomany(             db_field,             request,             **kwargs         )      def save_model(self, request, group, form, change):         perms = []         for p in group.permissions.all():             if p.codename.startswith('add_') or \                  p.codename.startswith('change_') or \                  p.codename.startswith('delete_'):                 perms.append(p)         super(GroupAdmin, self).save_model(request, group, form, change)         form.cleaned_data['permissions'] = list(             form.cleaned_data['permissions']         )         if not request.user.is_superuser:             form.cleaned_data['permissions'].extend(perms)         form.cleaned_data['permissions'] = list(set(             form.cleaned_data['permissions']))         group.save()   # register new user admin admin.site.unregister(User) admin.site.register(User, UserAdmin) admin.site.unregister(Group) admin.site.register(Group, GroupAdmin) 

When i developing and run devserver on localhost anything work nice, but on the server and by domain i can't submit this form by The connection was reset message. Below code is my apache2 configs:

<VirtualHost *:80>      DocumentRoot "/var/www/wordpress"  #    ServerName localhost  #    Alias /wordpress /var/www/wordpress #    <Directory /var/www/wordpress> #        Options Indexes FollowSymLinks #        AllowOverride None #        Order Deny,Allow #        Allow from all #    </Directory>      WSGIScriptAlias /m3s /var/www/m3s/HomeMakers/wsgi.py     #ProxyPass        /m3s/ http://127.0.0.1:8000/     #ProxyPassReverse /m3s/ http://127.0.0.1:8000/     #<Proxy http://127.0.0.1:8000/m3s/>     #    Order Allow,Deny     #    Allow from all     #</Proxy>       # WSGIDaemonProcess sentry python-path=/var/www/sentry/venv/lib/python2.7/site-packages     # WSGIScriptAlias /exceptions/tracker /var/www/sentry/venv/lib/python2.7/site-packages/sentry/wsgi.py      Alias /ufiles  /var/www/m3s/media_files     Alias /static /var/www/m3s/sfiles     Alias /_static /var/www/sentry/venv/lib/python2.7/site-packages/sentry/static     Alias /mydb/admin /usr/share/phpmyadmin      <Directory "/var/www/m3s/HomeMakers/">         Options +ExecCGI         Order allow,deny         Allow from all         Require all granted     </Directory>      <Directory /var/www/m3s/sfiles/>         Order allow,deny         Allow from all     </Directory>      ErrorLog ${APACHE_LOG_DIR}/error.log     CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost> 

Also i tried to using uwsgi and mod_proxy together but my problem not resolved. After i monitor access.log and my server port 80 by tshark, tshard shows me this request but in access.log file i can't see any change...

Apache logs in info mode:

[Sun Jan 29 21:15:47.896062 2017] [wsgi:warn] [pid 7596] mod_wsgi: Compiled for Python/2.7.11. [Sun Jan 29 21:15:47.896100 2017] [wsgi:warn] [pid 7596] mod_wsgi: Runtime using Python/2.7.11+. [Sun Jan 29 21:15:47.898887 2017] [mpm_prefork:notice] [pid 7596] AH00163: Apache/2.4.18 (Ubuntu) mod_wsgi/4.3.0 Python/2.7.11+ configured -- resuming normal operations [Sun Jan 29 21:15:47.898913 2017] [core:notice] [pid 7596] AH00094: Command line: '/usr/sbin/apache2' [Sun Jan 29 21:16:43.833245 2017] [wsgi:info] [pid 7599] [client 84.241.62.118:44316] mod_wsgi (pid=7599, process='', application='ut3taavoni.ir|/m3s'): Loading WSGI script '/var/www/m3s/HomeMakers/wsgi.py'. [Sun Jan 29 21:16:45.317557 2017] [wsgi:error] [pid 7599] DEBUG 2017-01-29 21:16:45,317 base 7599 -1220638144 Configuring Raven for host: <raven.conf.remote.RemoteConfig object at 0xada5a12c> [Sun Jan 29 21:16:47.484799 2017] [wsgi:info] [pid 7602] [client 84.241.62.118:42751] mod_wsgi (pid=7602, process='', application='ut3taavoni.ir|/m3s'): Loading WSGI script '/var/www/m3s/HomeMakers/wsgi.py'., referer: http://ut3taavoni.ir/m3s/m3s-panel/members/user/501/?_changelist_filters=q%3D0065231619 [Sun Jan 29 21:16:48.899865 2017] [wsgi:error] [pid 7602] DEBUG 2017-01-29 21:16:48,899 base 7602 -1220638144 Configuring Raven for host: <raven.conf.remote.RemoteConfig object at 0xada5a12c> [Sun Jan 29 21:17:33.961983 2017] [wsgi:info] [pid 7603] [client 84.241.62.118:20515] mod_wsgi (pid=7603, process='', application='ut3taavoni.ir|/m3s'): Loading WSGI script '/var/www/m3s/HomeMakers/wsgi.py'., referer: http://ut3taavoni.ir/m3s/m3s-panel/members/user/501/?_changelist_filters=q%3D0065231619 [Sun Jan 29 21:17:35.360116 2017] [wsgi:error] [pid 7603] DEBUG 2017-01-29 21:17:35,360 base 7603 -1220638144 Configuring Raven for host: <raven.conf.remote.RemoteConfig object at 0xada5a1ac> 

And my access.log file content:

192.0.102.40 - - [29/Jan/2017:22:37:30 +0330] "HEAD / HTTP/1.1" 200 372 "-" "jetmon/1.0 (Jetpack Site Uptime Monitor by WordPress.com)" xxx.241.62.118 - - [29/Jan/2017:22:37:56 +0330] "GET /m3s/m3s-panel/members/user/ HTTP/1.1" 200 4627 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" xxx.241.62.118 - - [29/Jan/2017:22:37:57 +0330] "GET /m3s/m3s-panel/jsi18n/ HTTP/1.1" 200 10588 "http://ut3taavoni.ir/m3s/m3s-panel/members/user/" "Mozilla/5.0 (X11; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" xxx.241.62.118 - - [29/Jan/2017:22:38:51 +0330] "GET /m3s/m3s-panel/members/user/?q=0065231619 HTTP/1.1" 200 4195 "http://ut3taavoni.ir/m3s/m3s-panel/members/user/" "Mozilla/5.0 (X11; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" xxx.241.62.118 - - [29/Jan/2017:22:38:51 +0330] "GET /m3s/m3s-panel/jsi18n/ HTTP/1.1" 200 10588 "http://ut3taavoni.ir/m3s/m3s-panel/members/user/?q=0065231619" "Mozilla/5.0 (X11; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" xxx.241.62.118 - - [29/Jan/2017:22:38:54 +0330] "GET /m3s/m3s-panel/members/user/501/?_changelist_filters=q%3D0065231619 HTTP/1.1" 200 14967 "http://ut3taavoni.ir/m3s/m3s-panel/members/user/?q=0065231619" "Mozilla/5.0 (X11; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" xxx.241.62.118 - - [29/Jan/2017:22:38:55 +0330] "GET /m3s/m3s-panel/jsi18n/ HTTP/1.1" 200 10588 "http://ut3taavoni.ir/m3s/m3s-panel/members/user/501/?_changelist_filters=q%3D0065231619" "Mozilla/5.0 (X11; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" xxx.241.62.118 - - [29/Jan/2017:22:38:55 +0330] "GET /m3s/_nested_admin/server-data.js HTTP/1.1" 200 388 "http://ut3taavoni.ir/m3s/m3s-panel/members/user/501/?_changelist_filters=q%3D0065231619" "Mozilla/5.0 (X11; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" 

My related question on ServerFault site: http://serverfault.com/questions/827813/apache-respons-to-get-but-not-to-post

Update:
I ran tshark again and saw below important line:

7 0.754812317  5.113.18.90 -> xxx.156.28.145 HTTP 1434 POST /m3s/m3s-panel/members/user/501/ HTTP/1.1 [Malformed Packet] 

Below is my browser "Request Payload":

Content-Type: multipart/form-data; boundary=---------------------------51995842320268179811054389612 Content-Length: 4614  -----------------------------51995842320268179811054389612 Content-Disposition: form-data; name="csrfmiddlewaretoken"  STMAQ1bSTuWsl9CelQBK5S2QjUKIfZ1Z -----------------------------51995842320268179811054389612 Content-Disposition: form-data; name="username"  9265291619 -----------------------------51995842320268179811054389612 Content-Disposition: form-data; name="first_name"  اعظم -----------------------------51995842320268179811054389612 Content-Disposition: form-data; name="last_name"  جعفری -----------------------------51995842320268179811054389612 Content-Disposition: form-data; name="email"  jafariphd@ut.ac.ir -----------------------------51995842320268179811054389612 Content-Disposition: form-data; name="gender"  0 -----------------------------51995842320268179811054389612 Content-Disposition: form-data; name="birth_date_0"  15 -----------------------------51995842320268179811054389612 Content-Disposition: form-data; name="birth_date_1"  6 -----------------------------51995842320268179811054389612 Content-Disposition: form-data; name="birth_date_2"  1356 -----------------------------51995842320268179811054389612 Content-Disposition: form-data; name="academic_degree"  5 -----------------------------51995842320268179811054389612 Content-Disposition: form-data; name="picture"; filename="" Content-Type: application/octet-stream   -----------------------------51995842320268179811054389612 Content-Disposition: form-data; name="international_card_scaned_file"; filename="" Content-Type: application/octet-stream   -----------------------------51995842320268179811054389612 Content-Disposition: form-data; name="certificate_scaned_file_page1"; filename="" Content-Type: application/octet-stream   -----------------------------51995842320268179811054389612 Content-Disposition: form-data; name="certificate_scaned_file_page2"; filename="" Content-Type: application/octet-stream   -----------------------------51995842320268179811054389612 Content-Disposition: form-data; name="academic_degree_scaned_file"; filename="" Content-Type: application/octet-stream   -----------------------------51995842320268179811054389612 Content-Disposition: form-data; name="job_edict_document"; filename="" Content-Type: application/octet-stream   -----------------------------51995842320268179811054389612 Content-Disposition: form-data; name="certificate_no"  11909 -----------------------------51995842320268179811054389612 Content-Disposition: form-data; name="birth_place"  تهران -----------------------------51995842320268179811054389612 Content-Disposition: form-data; name="address"  تهران -میدان پاستور-خ پاستور غربی-خ آژیده-کوچه آفین-پ 7-طبقه اول غربی -----------------------------51995842320268179811054389612 Content-Disposition: form-data; name="home_phone"  66915902 -----------------------------51995842320268179811054389612 Content-Disposition: form-data; name="work_phone"  66409696 -----------------------------51995842320268179811054389612 Content-Disposition: form-data; name="mobile"  09125114282 -----------------------------51995842320268179811054389612 Content-Disposition: form-data; name="personnel_code"  26687 -----------------------------51995842320268179811054389612 Content-Disposition: form-data; name="job_field"  1 -----------------------------51995842320268179811054389612 Content-Disposition: form-data; name="self_employed_job_name"  کارشناس معماری -----------------------------51995842320268179811054389612 Content-Disposition: form-data; name="employment_type"  3 -----------------------------51995842320268179811054389612 Content-Disposition: form-data; name="start_date_0"  1 -----------------------------51995842320268179811054389612 Content-Disposition: form-data; name="start_date_1"  1 -----------------------------51995842320268179811054389612 Content-Disposition: form-data; name="start_date_2"  1385 -----------------------------51995842320268179811054389612 Content-Disposition: form-data; name="is_active"  on -----------------------------51995842320268179811054389612 Content-Disposition: form-data; name="is_staff"  on -----------------------------51995842320268179811054389612 Content-Disposition: form-data; name="groups"  3 -----------------------------51995842320268179811054389612 Content-Disposition: form-data; name="_continue"  ذخیره و ادامهٔ ویرایش -----------------------------51995842320268179811054389612-- 

But now my questions is how this problem happend and how can i resolve this?

1 Answers

Answers 1

We have the same issue on freshly installed system with Apache 2.4 on CentOS 6 64bit. Apache drops connections some time, it was behind nginx, so we get 502 Gateway error very often. There were nothing in logs, nothing with enabled debug, no crash dumps and so on.

The only solution that fixes the problem - rebuild/reinstall apache completely. We've found this solution after we add debug output code to apache sources, rebuild and have no issues, wondering how our debug code fixes the problem :) But it was rebuild.

P.S. Also carefully follow this recommendations on debug WSGI http://modwsgi.readthedocs.io/en/develop/user-guides/debugging-techniques.html

Read More

Tuesday, February 7, 2017

Django admin nested form can't submit, connection was reset

Leave a Comment

I have a django nested admin form and below code is my admin.py file content:

# -*- coding:utf-8 -*- from django.db.models import Q from django import forms  from django.contrib.auth.admin import UserAdmin as AuthUserAdmin from django.contrib import admin from django.contrib.auth.forms import UserCreationForm, UserChangeForm from django.contrib.auth.hashers import UNUSABLE_PASSWORD_PREFIX, identify_hasher from django.forms.utils import flatatt from django.utils.html import format_html from django.utils.safestring import mark_safe from django.utils.translation import ugettext as _, ugettext from django.contrib.auth.models import Group, Permission from nested_admin.nested import NestedStackedInline, NestedModelAdmin  from HomeMakers.apps.system.models import Dependant, Benefit, User, \     Unit, Stack, Parking from mtools.fields import UniqueValueWidget, PersianDateField   class DependantAdminForm(forms.ModelForm):     model = Dependant     birth_date = PersianDateField(label=u'تاریخ تولد')   class DependantAdmin(NestedStackedInline):     model = Dependant     form = DependantAdminForm      extra = 0     exclude = ['changed_status', 'new_obj']     can_delete = True   class BenefitSubAdmin(admin.TabularInline):     model = Benefit     extra = 1     min_num = 0      exclude = ['changed_status', 'new_obj']     can_delete = True   class NewUserAdminForm(UserCreationForm):     class Meta(UserCreationForm.Meta):         model = User      username = forms.RegexField(label=u"کد ملی", max_length=30, regex=r'^\d{8,10}$',                                 widget=UniqueValueWidget,                                 error_messages={'invalid': u"مقدار وارد شده قابل قبول نمیباشد."})     birth_date = PersianDateField(from_year=1290, to_year=1400, label=_('Birth Date'))     start_date = PersianDateField(from_year=1290, to_year=1400, label=u"تاریخ شروع به کار")      def clean_username(self):         # Since User.username is unique, this check is redundant,         # but it sets a nicer error message than the ORM. See #13147.         username = self.cleaned_data["username"]         if User.objects.filter(username=username).count() > 0:             raise forms.ValidationError(self.error_messages['duplicate_username'])         return username   class ReadOnlyPasswordHashWidget(forms.Widget):     def render(self, name, value, attrs):         encoded = value         final_attrs = self.build_attrs(attrs)          if not encoded or encoded.startswith(UNUSABLE_PASSWORD_PREFIX):             summary = mark_safe(u"<strong>%s</strong>" % _("No password set."))         else:             try:                 hasher = identify_hasher(encoded)             except ValueError:                 summary = mark_safe(u"<strong>%s</strong>" % _(                     "Invalid password format or unknown hashing algorithm."))             else:                 summary = u'''format_html_join('',                                            "<strong>{0}</strong>: {1} ",                                            ((ugettext(key), value)                                             for key, value in hasher.safe_summary(encoded).items())                                            )'''          return format_html(u"<div{0}>{1}</div>", flatatt(final_attrs), summary)   class ReadOnlyPasswordHashField(forms.Field):     widget = ReadOnlyPasswordHashWidget      def __init__(self, *args, **kwargs):         kwargs.setdefault("required", False)         super(ReadOnlyPasswordHashField, self).__init__(*args, **kwargs)      def bound_data(self, data, initial):         # Always return initial because the widget doesn't         # render an input field.         return initial      def _has_changed(self, initial, data):         return False   class EditUserAdminForm(UserChangeForm):     class Meta(UserChangeForm.Meta):         model = User      birth_date = PersianDateField(from_year=1290, to_year=1400, label=_('Birth Date'))     start_date = PersianDateField(from_year=1290, to_year=1400, label=u"تاریخ شروع به کار")     password = ReadOnlyPasswordHashField(label=_("Password"),         help_text=_("Raw passwords are not stored, so there is no way to see "                     "this user's password, but you can change the password "                     "using <a href=\"password/\">this form</a>."))      error_messages = {'duplicate_username': 'An user by this international code already exists.'}      def __init__(self, *args, **kwargs):         super(EditUserAdminForm, self).__init__(*args, **kwargs)         self.fields['username'] = forms.RegexField(label=u"کد ملی", max_length=30, regex=r'^\d{8,10}$',                                                    widget=UniqueValueWidget(),                                                    error_messages={'invalid': u"مقدار وارد شده قابل قبول نمیباشد."})         self.fields['username'].widget.attrs['value'] = self.instance.username      def clean_username(self):         # Since User.username is unique, this check is redundant,         # but it sets a nicer error message than the ORM. See #13147.         username = self.cleaned_data["username"]         if username != self.instance.username and User.objects.filter(username=username).count() > 0:             raise forms.ValidationError(self.error_messages['duplicate_username'])         return username   class UnitForm(forms.ModelForm):     model = Unit     installment_begin_date = PersianDateField(label=u'تاریخ شروع اقساط')   class StackSubAdmin(NestedStackedInline):     model = Stack     extra = 1   class ParkingSubAdmin(NestedStackedInline):     model = Parking     extra = 1   class UnitSubAdmin(NestedStackedInline):  #(admin.StackedInline):     model = Unit     form = UnitForm     extra = 0      inlines = [ParkingSubAdmin, StackSubAdmin]     exclude = ['sum_of_pays', 'parkings', 'warehouse']   class UserAdmin(AuthUserAdmin, NestedModelAdmin):     model = User     ordering = ['last_name']     list_per_page = 10     add_form = NewUserAdminForm     form = EditUserAdminForm     list_display = ['user_thumb', 'first_name', 'last_name']      list_filter = ['units__project', 'groups']      formfield_overrides = {         # models.DateField: {'widget': PersianDateWidget}     }      '''fields = (         'username', 'password', 'first_name', 'last_name', 'email',         'gender', 'birth_date', 'picture', 'certificate_no', 'birth_place', 'address', 'home_phone', 'work_phone',         'mobile', 'personnel_code', 'international_code', 'job_field', 'self_employed_job_name', 'employment_type',         'start_date', 'is_retired'     )'''      inlines = [DependantAdmin, UnitSubAdmin]  # & BenefitSubAdmin      def get_fieldsets(self, request, obj=None):         key_fields = {'fields': ('username', 'password1', 'password2')}         if obj is not None:             key_fields = {'fields': ('username', 'password')}          fieldsets = (             (None, key_fields),             (u'اطلاعات تکمیلی', {'fields': (                 'first_name', 'last_name', 'email',                 'gender', 'birth_date', 'academic_degree', 'picture', 'international_card_scaned_file',                 'certificate_scaned_file_page1', 'certificate_scaned_file_page2', 'academic_degree_scaned_file',                 'job_edict_document', 'certificate_no', 'birth_place', 'address', 'home_phone', 'work_phone',                 'mobile', 'personnel_code', 'job_field', 'self_employed_job_name', 'employment_type', 'start_date',                 'is_retired'                 )}              ),             (u'سطوح دسترسی', {'fields': ('is_active', 'is_staff', 'groups')})             # , 'user_permissions', 'is_superuser')}),             #  (u'تاریخ های مهم', {'fields': ('last_login', 'date_joined')})         )         if request.user.is_superuser:             fieldsets = (                 (None, key_fields),                 (u'اطلاعات تکمیلی', {'fields': (                     'first_name', 'last_name', 'email',                     'gender', 'birth_date', 'academic_degree', 'picture', 'international_card_scaned_file',                     'certificate_scaned_file_page1', 'certificate_scaned_file_page2', 'academic_degree_scaned_file',                     'job_edict_document', 'certificate_no', 'birth_place', 'address', 'home_phone', 'work_phone',                     'mobile', 'personnel_code', 'job_field', 'self_employed_job_name', 'employment_type', 'start_date',                     'is_retired'                     )}                  ),                 (u'سطوح دسترسی', {'fields': (                          'is_active',                          'is_staff',                          'is_superuser',                          'user_permissions',                          'groups'                     )                 })                 #  (u'تاریخ های مهم', {'fields': ('last_login', 'date_joined')})             )         return fieldsets      def get_queryset(self, request):         if request.user.is_superuser:             return User.objects.all()         return User.objects.filter(is_superuser=False)   class GroupAdmin(admin.ModelAdmin):     model = Group     filter_horizontal = ('permissions',)      def formfield_for_manytomany(self, db_field, request, **kwargs):         if db_field.name == "permissions" and not request.user.is_superuser:             kwargs["queryset"] = Permission.objects.exclude(                 Q(codename__startswith='add_') |                 Q(codename__startswith='change_') |                 Q(codename__startswith='delete_')             )         return super(GroupAdmin, self).formfield_for_manytomany(             db_field,             request,             **kwargs         )      def save_model(self, request, group, form, change):         perms = []         for p in group.permissions.all():             if p.codename.startswith('add_') or \                  p.codename.startswith('change_') or \                  p.codename.startswith('delete_'):                 perms.append(p)         super(GroupAdmin, self).save_model(request, group, form, change)         form.cleaned_data['permissions'] = list(             form.cleaned_data['permissions']         )         if not request.user.is_superuser:             form.cleaned_data['permissions'].extend(perms)         form.cleaned_data['permissions'] = list(set(             form.cleaned_data['permissions']))         group.save()   # register new user admin admin.site.unregister(User) admin.site.register(User, UserAdmin) admin.site.unregister(Group) admin.site.register(Group, GroupAdmin) 

When i developing and run devserver on localhost anything work nice, but on the server and by domain i can't submit this form by The connection was reset message. Below code is my apache2 configs:

<VirtualHost *:80>      DocumentRoot "/var/www/wordpress"  #    ServerName localhost  #    Alias /wordpress /var/www/wordpress #    <Directory /var/www/wordpress> #        Options Indexes FollowSymLinks #        AllowOverride None #        Order Deny,Allow #        Allow from all #    </Directory>      WSGIScriptAlias /m3s /var/www/m3s/HomeMakers/wsgi.py     #ProxyPass        /m3s/ http://127.0.0.1:8000/     #ProxyPassReverse /m3s/ http://127.0.0.1:8000/     #<Proxy http://127.0.0.1:8000/m3s/>     #    Order Allow,Deny     #    Allow from all     #</Proxy>       # WSGIDaemonProcess sentry python-path=/var/www/sentry/venv/lib/python2.7/site-packages     # WSGIScriptAlias /exceptions/tracker /var/www/sentry/venv/lib/python2.7/site-packages/sentry/wsgi.py      Alias /ufiles  /var/www/m3s/media_files     Alias /static /var/www/m3s/sfiles     Alias /_static /var/www/sentry/venv/lib/python2.7/site-packages/sentry/static     Alias /mydb/admin /usr/share/phpmyadmin      <Directory "/var/www/m3s/HomeMakers/">         Options +ExecCGI         Order allow,deny         Allow from all         Require all granted     </Directory>      <Directory /var/www/m3s/sfiles/>         Order allow,deny         Allow from all     </Directory>      ErrorLog ${APACHE_LOG_DIR}/error.log     CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost> 

Also i tried to using uwsgi and mod_proxy together but my problem not resolved. After i monitor access.log and my server port 80 by tshark, tshard shows me this request but in access.log file i can't see any change...

Apache logs in info mode:

[Sun Jan 29 21:15:47.896062 2017] [wsgi:warn] [pid 7596] mod_wsgi: Compiled for Python/2.7.11. [Sun Jan 29 21:15:47.896100 2017] [wsgi:warn] [pid 7596] mod_wsgi: Runtime using Python/2.7.11+. [Sun Jan 29 21:15:47.898887 2017] [mpm_prefork:notice] [pid 7596] AH00163: Apache/2.4.18 (Ubuntu) mod_wsgi/4.3.0 Python/2.7.11+ configured -- resuming normal operations [Sun Jan 29 21:15:47.898913 2017] [core:notice] [pid 7596] AH00094: Command line: '/usr/sbin/apache2' [Sun Jan 29 21:16:43.833245 2017] [wsgi:info] [pid 7599] [client 84.241.62.118:44316] mod_wsgi (pid=7599, process='', application='ut3taavoni.ir|/m3s'): Loading WSGI script '/var/www/m3s/HomeMakers/wsgi.py'. [Sun Jan 29 21:16:45.317557 2017] [wsgi:error] [pid 7599] DEBUG 2017-01-29 21:16:45,317 base 7599 -1220638144 Configuring Raven for host: <raven.conf.remote.RemoteConfig object at 0xada5a12c> [Sun Jan 29 21:16:47.484799 2017] [wsgi:info] [pid 7602] [client 84.241.62.118:42751] mod_wsgi (pid=7602, process='', application='ut3taavoni.ir|/m3s'): Loading WSGI script '/var/www/m3s/HomeMakers/wsgi.py'., referer: http://ut3taavoni.ir/m3s/m3s-panel/members/user/501/?_changelist_filters=q%3D0065231619 [Sun Jan 29 21:16:48.899865 2017] [wsgi:error] [pid 7602] DEBUG 2017-01-29 21:16:48,899 base 7602 -1220638144 Configuring Raven for host: <raven.conf.remote.RemoteConfig object at 0xada5a12c> [Sun Jan 29 21:17:33.961983 2017] [wsgi:info] [pid 7603] [client 84.241.62.118:20515] mod_wsgi (pid=7603, process='', application='ut3taavoni.ir|/m3s'): Loading WSGI script '/var/www/m3s/HomeMakers/wsgi.py'., referer: http://ut3taavoni.ir/m3s/m3s-panel/members/user/501/?_changelist_filters=q%3D0065231619 [Sun Jan 29 21:17:35.360116 2017] [wsgi:error] [pid 7603] DEBUG 2017-01-29 21:17:35,360 base 7603 -1220638144 Configuring Raven for host: <raven.conf.remote.RemoteConfig object at 0xada5a1ac> 

And my access.log file content:

192.0.102.40 - - [29/Jan/2017:22:37:30 +0330] "HEAD / HTTP/1.1" 200 372 "-" "jetmon/1.0 (Jetpack Site Uptime Monitor by WordPress.com)" xxx.241.62.118 - - [29/Jan/2017:22:37:56 +0330] "GET /m3s/m3s-panel/members/user/ HTTP/1.1" 200 4627 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" xxx.241.62.118 - - [29/Jan/2017:22:37:57 +0330] "GET /m3s/m3s-panel/jsi18n/ HTTP/1.1" 200 10588 "http://ut3taavoni.ir/m3s/m3s-panel/members/user/" "Mozilla/5.0 (X11; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" xxx.241.62.118 - - [29/Jan/2017:22:38:51 +0330] "GET /m3s/m3s-panel/members/user/?q=0065231619 HTTP/1.1" 200 4195 "http://ut3taavoni.ir/m3s/m3s-panel/members/user/" "Mozilla/5.0 (X11; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" xxx.241.62.118 - - [29/Jan/2017:22:38:51 +0330] "GET /m3s/m3s-panel/jsi18n/ HTTP/1.1" 200 10588 "http://ut3taavoni.ir/m3s/m3s-panel/members/user/?q=0065231619" "Mozilla/5.0 (X11; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" xxx.241.62.118 - - [29/Jan/2017:22:38:54 +0330] "GET /m3s/m3s-panel/members/user/501/?_changelist_filters=q%3D0065231619 HTTP/1.1" 200 14967 "http://ut3taavoni.ir/m3s/m3s-panel/members/user/?q=0065231619" "Mozilla/5.0 (X11; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" xxx.241.62.118 - - [29/Jan/2017:22:38:55 +0330] "GET /m3s/m3s-panel/jsi18n/ HTTP/1.1" 200 10588 "http://ut3taavoni.ir/m3s/m3s-panel/members/user/501/?_changelist_filters=q%3D0065231619" "Mozilla/5.0 (X11; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" xxx.241.62.118 - - [29/Jan/2017:22:38:55 +0330] "GET /m3s/_nested_admin/server-data.js HTTP/1.1" 200 388 "http://ut3taavoni.ir/m3s/m3s-panel/members/user/501/?_changelist_filters=q%3D0065231619" "Mozilla/5.0 (X11; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" 

My related question on ServerFault site: http://serverfault.com/questions/827813/apache-respons-to-get-but-not-to-post

1 Answers

Answers 1

We have the same issue on freshly installed system with Apache 2.4 on CentOS 6 64bit. Apache drops connections some time, it was behind nginx, so we get 502 Gateway error very often. There were nothing in logs, nothing with enabled debug, no crash dumps and so on.

The only solution that fixes the problem - rebuild/reinstall apache completely. We've found this solution after we add debug output code to apache sources, rebuild and have no issues, wondering how our debug code fixes the problem :) But it was rebuild.

P.S. Also carefully follow this recommendations on debug WSGI http://modwsgi.readthedocs.io/en/develop/user-guides/debugging-techniques.html

Read More

Thursday, August 4, 2016

django admin - how to override add new row in an inlined formset

Leave a Comment

I've customised my inlined model using the Media class. I want to customize the inlined field sets to achieve 2 things:

  • add a button to each row
  • run from javascript code when "add new row" is pressed

I've tried overriding tabular.html and no matter where I put the overriden template, it does not make any difference.

From playing with the change_form.html I can say that I need to override inline_admin_formset.opts.template but I do not know how. Any ideas?

enter image description here

0 Answers

Read More

Friday, April 8, 2016

Django- When using Inline Function process aborted

Leave a Comment

I am facing a strange road block in my django Admin.

when i am using inline=[inlineFunction]

Then it fires process status aborted error.

Here is my code..

 class ApplicationInline(admin.TabularInline):     """     inline class Application     """     model = Application     show_change_link = True     extra = 0     list_per_page = 2      def formfield_for_dbfield(self, db_field, **kwargs):         if db_field.name == 'logo':             request = kwargs.pop("request", None)             kwargs['widget'] = AdminApplicationLogoWidget              return db_field.formfield(**kwargs)         return super(ApplicationInline,                      self).formfield_for_dbfield(db_field, **kwargs)   class CategoryAdmin(admin.ModelAdmin):     """     custom Admin Class for category model     """     list_display = ['name_row_1', 'create_date', 'hospital', 'speciality',   'sort_order']     search_fields = ['name_row_1', 'hospital__name', 'speciality__name']     inlines = [ApplicationInline]     list_per_page = settings.ADMIN_PAGE_SIZE      class Media:         js = (               'v1/js/jquery.min.js',               'v1/js/inline/function_categories.js'         )      def formfield_for_dbfield(self, db_field, **kwargs):         if db_field.name == 'logo':             request = kwargs.pop("request", None)             kwargs['widget'] = AdminCategoryLogoWidget              return db_field.formfield(**kwargs)         return super(CategoryAdmin,                      self).formfield_for_dbfield(db_field,                                                  **kwargs)      # Default Select Options in Action     BLANK_CHOICE_DASH = [("", "Select options")]      def get_action_choices(self, request, default_choices=BLANK_CHOICE_DASH):         """         Return a list of choices for use in a form object.  Each choice is a         tuple (name, description).         """         choices = [] + default_choices          for func, name, description in six.itervalues(self.get_actions(request)):             choice = (name, description % model_format_dict(self.opts))             choices.append(choice)         return choices 

When i add inlines = [ApplicationInline] in my code then on browser page loads again and again.

On my local server it works fine.

My problem is : When i click on save button then browser only loading again and again and not doing any action.

I think this is not code problem because code is running on my local server(windows machine) but on client server only on a single page that error occurs. I don't know what is error. Because not any fault in my code. Not any error show in console.

Client server is AWS/Linux.

Acc. to me, this error occurs in admin section only on linux server, Not any other server. I check same code run on other server that's working. But only not working on AWS/linux server.

0 Answers

Read More